#include "Channels.h"
#include "ChannelManager.h"
#include "Resource.h"
#include "String.h"
#include "SharedPtr.h"
#include "ResourceManager.h"
#include "Database/DatabaseEnv.h"
#include "StringConverter.h"
#include "NGLog.h"
#include "Character.h"
#include "CharManager.h"
#include "Items.h"
#include "ItemManager.h"
#include "WorldPacket.h"
#include "Opcodes.h"
#include "RegionManager.h"
#include "Towns.h"
#include "TownManager.h"
#include "Users.h"
#include "UserManager.h"
#include "Mails.h"
#include "MailManager.h"
#include "WSSocket.h"
#include "WSSocketManager.h"
#include "Missions.h"
#include "MissionManager.h"
#include "Message.h"
#include "MD5.h"
#include "Titles.h"
#include "TitleManager.h"
#include <curl/curl.h>
#include "AIInterface.h"
#include "GameDataEnum.h"
#include "ProtocolDealEnums.h"
#include "ResourceEventEnum.h"
#include "GameThreadLogic.h"
#include "CenterBankManager.h"
#include "CenterHappyFarmManager.h"
#include "CenterFriendManager.h"
#include "CenterMatchManager.h"
#include "CenterClubManager.h"
#include "GameDefine.h"
#include LOG_MGR_PATH
#include LOGIC_MGR_PATH
#include HALL_MGR_PATH
#include PROTOCOLS_MGR_PATH
#include XMLDATA_MGR_PATH
#include "VipCardManager.h"
#include "Tools.h"
#include "showip.h"
#include "NoticeManager.h"
#include "OpcodesEx.h"
#include "DataTransferManager.h"
#include "ServerManager.h"
#include "json/json.h"
#include "CRUsersManager.h"
#include "CRGeolocationManager.h"
#include "UserGameLogsManager.h"
#include "url.h"
#include "MD5.h"
#include <queue>
#include "rapidjson/rapidjson.h"
#include "rapidjson/document.h"
#include "rapidjson/writer.h"


#define SECUREKEY "mef3mervzl1SykohhufmdkhvdbCpokkt"

using namespace rapidjson;
using namespace AIScript;


String unbase64Ex(String input) 
{
	size_t length = input.size();
	char *buffer = (char *)malloc(length); 
	memset(buffer, 0, length); 

	BIO *b64, *bmem; 
	b64 = BIO_new(BIO_f_base64()); 
	BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
	bmem = BIO_new_mem_buf((void*)input.c_str(), length); 
	bmem = BIO_push(b64, bmem); 

	BIO_read(bmem, buffer, length); 

	BIO_free_all(bmem);
	String str(buffer);
	free(buffer);
	return str; 
}

//-----------------------------------------------------------------------
UserPtr 	GameLogicManager::CreateUser(const String &userName, const uint32 &platform_id)
{
	UserPtr pUser;
	/* std::vector<String> lstNames = StringUtil::split(userName,"-");
	if (lstNames.size() != 3)
		return pUser;
	uint32 gz_id = StringConverter::parseUnsignedInt(lstNames[0]);
	uint32 from_id = StringConverter::parseUnsignedInt(lstNames[1]);
	
	Resource *user = sUserMgr.newDumyUser();
	user->setUInt32Field("group_id", 1);
	user->setStringField("name", userName);
	user->setStringField("passwd", "888888");
	user->setStringField("passwd2", "21218cca77804d2ba1922c33e0151105");
	user->setStringField("nick", "贵宾");
	user->setUInt32Field("session_server", 1);
	user->setUInt32Field("valid", 1);
	user->setUInt32Field("reg_time", time(0));
	user->setUInt32Field("reg_from", from_id);
	user->setUInt32Field("platform_id", platform_id);
	user->setUInt32Field("gz_id", gz_id);
	user->setUInt32Field("ll_time", 0);
	pUser = sUserMgr.loadUserDatabase(user);
	sUserMgr.freeDumyUser(user);
	// pUser->load(); */
	return pUser;
}

//-----------------------------------------------------------------------
CharPtr 	GameLogicManager::CreateCreature(UserPtr & user, bool isCenter/*  = true */)
{
	CharPtr chr;
	if (user.isNull())
		return chr;
	std::list<CharPtr> chars;
	sCharMgr.getCharsList(&chars, 0, 1, "userid = %u", user->getHandle());
	if(!chars.empty())
	{
		chr = chars.front();
		user->setUInt32Field("char_id", chr->getHandle());
		return chars.front();
	}
	
	Resource * pChar = sCharMgr.newDumyChar();
	assert(pChar);
	pChar->setFloatField("x", (float)RandomUInt(100, 890));
	pChar->setFloatField("y", (float)RandomUInt(100, 890));
	pChar->setUInt32Field("id", RandomUInt(0,1) ? RandomUInt(511, 513) : RandomUInt(411, 414));	
	
	String name = user->getStringField("nick");
	int loc = name.find("贵宾", 0);
	if (loc != -1)
		name = GetNickWords();
	
	pChar->setStringField("name", ServerDatabase.EscapeString(name));
	pChar->setUInt32Field("userid", user->getHandle());
	pChar->setUInt32Field("lv", 1);
	pChar->setUInt32Field("exps", 0);
	pChar->setUInt32Field("status", CharacterStatusFree);
	pChar->setUInt32Field("gz_id", user->getUInt32Field("gz_id"));
	pChar->setUInt32Field("create_time", time(0));
	chr = sCharMgr.createCharDatabase(pChar);
	sCharMgr.freeDumyChar(pChar);
	chr->load();
	user->setStringField("passwd2", "21218cca77804d2ba1922c33e0151105");
	user->setUInt32Field("char_id", chr->getHandle());
	user->setStringField("nick", name);
	
	if(isCenter == false)
	{
		addItemNum(chr, ItemModel_Coins, sXmlDataMgr.GetConfXMLValue("INIT_COINS"));
		addItemNum(chr, ItemModel_Lottery, sXmlDataMgr.GetConfXMLValue("INIT_LOTTERY"));
	}
	else
	{
		addItemNum(chr, ItemModel_Coins, 0);
		addItemNum(chr, ItemModel_Lottery, 0);
	}
	
	return chr;
}

// 获取用户根据PID和GZID
CharPtr GameLogicManager::GetCharptrByPidAndGzid(const uint32 & platform_id, const uint32 & gz_id)
{
	CharPtr pChr;
	if(!platform_id || !gz_id)
		return pChr;
	
	std::list<ResourcePtr> lstUser;
	sUserMgr.getDBObjects(&lstUser, 0, 1, " platform_id = %u and gz_id = %u", platform_id, gz_id);
	if(lstUser.empty())
		return pChr;
	
	UserPtr pUser = sUserMgr.load((*lstUser.begin())->getUInt32Field("uid"));
	if(pUser.isNull())
		return pChr;
	
	pChr = sCharMgr.load(pUser->getUInt32Field("char_id"));
	return pChr;
}

uint32 GameLogicManager::GetGoldMoney(CharPtr & chr)
//-----------------------------------------------------------------------
{
	if(chr.isNull())
		return 0;
	uint32 userid = chr->getUInt32Field("userid");
	if(userid)
	{
		UserPtr user = sUserMgr.load(userid);
		if(user.isNull())
			return 0;
		return user->getUInt32Field("golds");		
	}
	return 0;
}

//-----------------------------------------------------------------------
void GameLogicManager::SetGoldMoney(CharPtr & chr, const uint32 gMoney)
{
	assert(!chr.isNull());
	uint32 userid = chr->getUInt32Field("userid");
	if(userid)
	{
		UserPtr user = sUserMgr.getByHandle(userid);
		assert(!user.isNull());
		user->setUInt32Field("golds", gMoney);	
		user->SaveDB();
		WSSocketPtr socket = chr->getSocket();
		if(!socket.isNull())
		{
			// 通知元宝数据更新
			WorldPacket newP;
			if(sProtocolsMgr.CreateGoldsUpdatePacket(&newP, gMoney))
				socket->SendPacket(&newP);
		}
	}
}

//-----------------------------------------------------------------------
String GameLogicManager::GetCurDateTime(time_t t)
{
	if (0 == t)
		t = time(0);
	tm ttm = *localtime(&t);
	return GetDateTime(&ttm);
}

//-----------------------------------------------------------------------
uint32 	GameLogicManager::GetCurDate(uint32 now_time)
{
	if(!now_time)
		now_time = time(0);
	
	time_t ti = (time_t)now_time;
	tm localTime = *localtime(&ti);
	char buf[20];
	strftime(buf, sizeof buf, "%Y%m%d", &localTime);
	return StringConverter::parseUnsignedInt(buf);
}

//-----------------------------------------------------------------------
uint32 GameLogicManager::GetCurTimer(void)
{
	char buf[20];
	strftime(buf, sizeof buf, "%H%M%S", &g_localTime);
	return StringConverter::parseUnsignedInt(buf);
}

//-----------------------------------------------------------------------
String GameLogicManager::GetDateTime(tm *pTm)
{
	char buf[20];
	strftime(buf, sizeof buf, "%Y-%m-%d %H:%M:%S", pTm);
	return buf;
}
//-----------------------------------------------------------------------
time_t GameLogicManager::GetDateTimeSeconds(String &str)
{
	if (str == "" || str == "0000-00-00 00:00:00")
		return 0;
	
	tm tmsd;
	memset(&tmsd, 0, sizeof(tmsd));
	sscanf(str.c_str(), "%4d-%2d-%2d %2d:%2d:%2d", &tmsd.tm_year, &tmsd.tm_mon, &tmsd.tm_mday, &tmsd.tm_hour, &tmsd.tm_min, &tmsd.tm_sec);
	tmsd.tm_year -= 1900;
	tmsd.tm_mon -= 1;
	return mktime(&tmsd);
}

//-----------------------------------------------------------------------
ItemPtr GameLogicManager::CreateItem(CharPtr & container, const uint32 & model_id, const uint32 & num, bool bSendPacket)
{
	ItemPtr item;
	if(container.isNull() || model_id == 0)
		return item;
	std::list<ItemPtr> items;
	container->getItemsList(&items);
	
	std::list<ItemPtr>::iterator iter,ei = items.end();
	for(iter = items.begin(); iter!=ei; ++iter)
	{
		if((*iter)->model->getHandle() == model_id)
			return item;
	}
	ItemModelPtr imp = sItemModelMgr.load(model_id);
	if(imp.isNull())
		return item;
	Resource * pItem = sItemMgr.newDumyItem(model_id);
	pItem->setUInt32Field("status", Item::ItemStatusNormal);
	pItem->setUInt32Field("model_id", model_id);
	pItem->setStringField("name", imp->getStringField("name"));
	pItem->setUInt32Field("container", container->getHandle());
	pItem->setUInt32Field("container_type", container->getTargetType());
	
	// 区分物品类型
	if (imp->getUInt32Field("type") == 2)
	{
		pItem->setUInt32Field("num", imp->getUInt32Field("value") * num);
		pItem->setUInt32Field("value", num);
	}
	else
	{
		pItem->setUInt32Field("num", num);
	}
	
	item = sItemMgr.createItemDatabase(pItem);
	sItemMgr.freeDumyItem(pItem);
	item->load();
	
	WSSocketPtr pSocket = container->getSocket();
	if (!pSocket.isNull() && bSendPacket)
	{
		WorldPacket newP;
		if(sProtocolsMgr.CreateUpdateItemNumberPacket(&newP, model_id, item->getUInt32Field("num")))
			pSocket->SendPacket(&newP);
	}
	UpdateAboutMoney(container, model_id, num);
	return item;
}

//-----------------------------------------------------------------------
ItemPtr GameLogicManager::CreateItemByScriptID(CharPtr & pChr, const uint32 & script_id)
{
	ItemPtr pItem;
	if(!script_id)
		return pItem;
	
	pItem = sItemMgr.CreateScript(script_id);
	if(!pItem.isNull())
	{
		pItem->setUInt32Field("container", pChr->getHandle());
		pItem->setUInt32Field("container_type", pChr->getTargetType());
		pItem->setUInt32Field("x", RandomUInt(1, 100));
		pItem->setUInt32Field("y", RandomUInt(1, 100));
		pItem->setUInt32Field("script_id", script_id);
		pItem->setUInt32Field("create_time", time(0));
		pItem->SaveDB();
		pItem->load();
		
		SendAddItemMessage(pChr, pItem->model->getHandle(), pItem->getUInt32Field("num"), "caijuan");		
		WorldPacket newP;
		ResourcePtr socket = pChr->getSocket();
		if(!socket.isNull() && sProtocolsMgr.CreateAddNewItemPacket(&newP, pItem))
			SendPacket(socket, &newP);
		
	}
	
	return pItem;
}

//-----------------------------------------------------------------------
void GameLogicManager::UpdateAboutMoney(CharPtr &pChr, const uint32 modelId, const uint32 num)
{
	if (pChr.isNull())
		return;
	switch (modelId)
	{
		case ItemModel_Coins: // 铜钱
			pChr->setUInt32Field("speed", num);
			break;
		case ItemModel_March: // 参赛券
			pChr->setUInt32Field("speed_org", num);
			break;
		case ItemModel_Lottery: // 兑换券
			pChr->setUInt32Field("speed2", num);
			break;
		case ItemModel_Golds:		// 人人券
			pChr->setUInt32Field("coins", num);
			break;
		case ItemModel_Flower:	// 鲜花
			pChr->setUInt32Field("color", num);
			break;
		default:
			return;
	}
	
	// pChr->SaveDB();
}

//-----------------------------------------------------------------------
bool GameLogicManager::SetItemNum(CharPtr & chr, const uint32 & model_id, const uint32 & num)
{
	std::list<ItemPtr> items;
	chr->getItemsList(&items);
	std::list<ItemPtr>::iterator ii, endii = items.end();
	for(ii = items.begin(); ii != endii; ++ ii)
	{
		if((*ii)->model->getHandle() == model_id)
		{
			(*ii)->setUInt32Field("num", num);
			(*ii)->SaveDB();
			
			ResourcePtr socket = chr->getSocket();			
			WorldPacket newP;
			if(sProtocolsMgr.CreateUpdateItemNumberPacket(&newP, model_id, (*ii)->getUInt32Field("num")))
				SendPacket(socket, &newP);
			UpdateAboutMoney(chr, model_id, num);
			return true;
		}
	}
	
	return false;
}

//-----------------------------------------------------------------------
ItemPtr GameLogicManager::addItemNum(CharPtr & chr, const uint32 & model_id, const uint32 & addnum, bool bUpdate)
{
	ItemPtr item = GetItem(chr, model_id);
	if(item.isNull())
		return CreateItem(chr, model_id, addnum);
	if (addnum == 0)
		return item;
	uint32 allNum = 0;
	// 区分物品类型
	if (item->model->getUInt32Field("type") == 2)
	{
		allNum = item->getUInt32Field("num") + item->model->getUInt32Field("value") * addnum;
		item->setUInt32Field("value", item->getUInt32Field("value") + addnum);
	}
	else
	{
		allNum = item->getUInt32Field("num") + addnum;
	}
	uint32 maxNumber = sXmlDataMgr.GetConfXMLValue("MAX_COINS");
	bool bSaveBank = false;
	uint32 leftNum = 0;
	if (allNum > maxNumber)
	{
		leftNum = allNum - maxNumber;
		allNum = maxNumber;
		UserPtr pUser = sUserMgr.getByHandle(chr->getUInt32Field("userid"));
		sBankMgr.SaveWealthInBank(pUser, model_id, leftNum);
		bSaveBank = true;
	}
	item->setUInt32Field("num", allNum);
	item->SaveDB();
	UpdateAboutMoney(chr, model_id, allNum);
	if (bUpdate)
	{
		// 下发更新物品数量
		WorldPacket newP;
		if(sProtocolsMgr.CreateUpdateItemNumberPacket(&newP, model_id, allNum))
			SendProtocolsToChr(chr, &newP);
	}
	
	// 财富成就
	if (model_id == ItemModel_Coins)
	{
		ResourceEvent event;
		event.event_id = en_EventBaseType_Wealth;
		event.idata = model_id;
		event.idata2 = allNum;
		chr->SendEvent(&event);
	}
	
	if(model_id == ItemModel_DiamondOpen)
	{
		sCenterClubMgr.UpdateClubActivityValueByCraeter(chr);
	}
	
	// 通知玩家携带现金超出上限，超出部分已存银行
	if (bSaveBank)
	{
		char msg[256];
		sprintf(msg, sMsg.getMessage("overflow").c_str(), leftNum, item->getItemName().c_str());
		SendSystemMessage(chr, msg, sMsg.getType("overflow"));
	}
	return item;
}

// 增加兑换道具数量
bool GameLogicManager::addExchangeItemNum(CharPtr & pChr, const uint32 & model_id, const uint32 & addnum, stGatewayExChangeInfo stGEC)
{
	if(pChr.isNull() || model_id == 0 || addnum == 0)
		return false;
	
	ItemPtr item;
	bool bAddNewItem = true;
	std::list<ItemPtr> lstItems;
	if(getItemListByModelid(pChr, model_id, &lstItems))
	{
		std::list<ItemPtr>::iterator iter, ei = lstItems.end();
		for(iter = lstItems.begin(); iter!=ei; ++iter)
		{
			if(stGEC.useful_expire_time.compare("0000-00-00 00:00:00"))
			{// 周期内有效，可找同类型堆叠。
				if((*iter)->getUInt32Field("destroy_time") == GetDateTimeSeconds(stGEC.useful_expire_time))
				{
					(*iter)->setUInt32Field("num", (*iter)->getUInt32Field("num") + addnum);
					item = *iter;
					bAddNewItem = false;
					break;
				}
			}
			else if(stGEC.useful_expire_relative_time == 0)
			{// 没有周期，也没有购买后的生效时期
				if((*iter)->getUInt32Field("destroy_time") == 0)
				{
					(*iter)->setUInt32Field("num", (*iter)->getUInt32Field("num") + addnum);
					item = *iter;
					bAddNewItem = false;
					break;
				}
			}
		}
	}
	
	if(bAddNewItem)
	{// 添加新道具
		ItemModelPtr imp = sItemModelMgr.load(model_id);
		if(imp.isNull())
			return false;
		
		Resource * pItem = sItemMgr.newDumyItem(model_id);
		pItem->setUInt32Field("status", Item::ItemStatusNormal);
		pItem->setUInt32Field("model_id", model_id);
		pItem->setStringField("name", imp->getStringField("name"));
		pItem->setUInt32Field("container", pChr->getHandle());
		pItem->setUInt32Field("container_type", pChr->getTargetType());
		
		if(stGEC.useful_expire_relative_time)
		{// 道具失效时间
			pItem->setUInt32Field("destroy_time", time(0) + stGEC.useful_expire_relative_time);
		}
		else if(stGEC.useful_expire_time.compare("0000-00-00 00:00:00"))
		{// 道具失效时间
			uint32 expir_time = GetDateTimeSeconds(stGEC.useful_expire_time);
			pItem->setUInt32Field("destroy_time", expir_time);
		}
		
		if(stGEC.useful_valid_time.compare("0000-00-00 00:00:00"))
		{// 道具生效时间
			uint32 valid_time = GetDateTimeSeconds(stGEC.useful_valid_time);
			pItem->setUInt32Field("handle_time", valid_time);
		}
		
		// 区分物品类型
		if (imp->getUInt32Field("type") == 2)
		{
			pItem->setUInt32Field("num", imp->getUInt32Field("value") * addnum);
			pItem->setUInt32Field("value", addnum);
		}
		else
		{
			pItem->setUInt32Field("num", addnum);
		}
		
		item = sItemMgr.createItemDatabase(pItem);
		sItemMgr.freeDumyItem(pItem);
		item->load();
	}
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateUpdateExchangeItemNumberPacket(&packet, item->getHandle(), item->getUInt32Field("model_id"), item->getUInt32Field("num")))
		SendProtocolsToChr(pChr, &packet);
	
	return true;
}

// 得到某个模式ID的道具列表
bool GameLogicManager::getItemListByModelid(CharPtr & pChr, const uint32 & model_id, std::list<ItemPtr> * lstItems)
{
	if(pChr.isNull() || lstItems == NULL)
		return false;
	
	lstItems->clear();
	
	std::list<ItemPtr> itemList;
	pChr->getItemsList(&itemList);
	
	std::list<ItemPtr>::iterator iter, ei = itemList.end();
	for(iter = itemList.begin(); iter!=ei; ++iter)
	{
		if((*iter)->getUInt32Field("model_id") == model_id)
			lstItems->push_back(*iter);
	}
	
	return lstItems->size() > 0;
}

//-----------------------------------------------------------------------
uint32 GameLogicManager::addCongealItemNum(CharPtr & pChr, const uint32 & model_id, const uint32 & addnum)
{
	ItemPtr item;
	if(model_id == 0)
		return 0;
	
	item = GetItem(pChr, model_id);
	if(item.isNull())
		return 0;
	
	uint32 allNum = item->getUInt32Field("value") + addnum;
	item->setUInt32Field("value", allNum);
	item->SaveDB();	
	
	return allNum;
}

//-----------------------------------------------------------------------
bool GameLogicManager::reduceCongealItemNum(CharPtr & pChr, const uint32 & model_id, const uint32 & rNum)
{
	ItemPtr item = GetItem(pChr, model_id);
	if(item.isNull())
		return false;
	
	uint32 cur_num = item->getUInt32Field("value");
	if(cur_num < rNum)
		return false;
	cur_num -= rNum;
	item->setUInt32Field("value", cur_num);	
	item->SaveDB();
	return true;
}

// 还原冻结物品数量
bool GameLogicManager::rebornCongealItemNum(CharPtr & pChr, const uint32 & model_id, const uint32 & rNum,bool bUpdate)
{
	ItemPtr item = GetItem(pChr, model_id);
	if(item.isNull())
		return false;
	
	uint32 cur_num = item->getUInt32Field("value");
	if(cur_num < rNum)
		return false;
	
	uint32 distance_num = 0;	//剩下的冻结刷量
	uint32 allNum = 0;	//剩下的物品数量
	if(rNum)
	{
		distance_num = cur_num - rNum;
		allNum = item->getUInt32Field("num") + rNum;
	}
	else	//全部还原
	{
		distance_num = 0;
		allNum = item->getUInt32Field("num") + cur_num;
	}
	
	item->setUInt32Field("value",distance_num);	
	item->setUInt32Field("num",allNum);
	item->SaveDB();
	
	if (bUpdate)
	{
		ResourcePtr socket = pChr->getSocket();
		if(!socket.isNull())
		{
			WorldPacket newP;
			if(sProtocolsMgr.CreateUpdateItemNumberPacket(&newP, model_id, allNum))
				SendPacket(socket, &newP);
		}
	}
	
	return true;
}

bool GameLogicManager::setCongealItemNum(CharPtr & pChr, const uint32 & model_id, const uint32 & num /* = 0 */)
{
	ItemPtr item = GetItem(pChr, model_id);
	if(item.isNull())
		return false;
	
	item->setUInt32Field("value", num);	
	item->SaveDB();
	return true;
}

//-----------------------------------------------------------------------
bool GameLogicManager::reduceItemNum(CharPtr & chr, const uint32 & model_id, const uint32 & rNum, bool isUpdate, bool isBlocked /* = false */)
{
	if(!rNum)
		return true;
	
	ItemPtr item = GetItem(chr, model_id);
	if(item.isNull())
		return false;
	
	uint32 cur_num = item->getUInt32Field("num");
	if(cur_num < rNum)
		return false;
	cur_num -= rNum;
	item->setUInt32Field("num", cur_num);	
	if(isBlocked)
		item->setUInt32Field("value", item->getUInt32Field("value") + rNum);
		
	item->SaveDB();
	if (isUpdate)
	{
		ResourcePtr socket = chr->getSocket();
		if(!socket.isNull())
		{
			WorldPacket newP;
			if(sProtocolsMgr.CreateUpdateItemNumberPacket(&newP, model_id, cur_num))
				SendPacket(socket, &newP);
		}
	}
	
	if(model_id == ItemModel_DiamondOpen)
	{
		sCenterClubMgr.UpdateClubActivityValueByCraeter(chr);
	}
	
	UpdateAboutMoney(chr, model_id, cur_num);
	return true;
}

//-----------------------------------------------------------------------
uint32 GameLogicManager::getCogealItemNum(CharPtr & pChr, const uint32 & model_id)
{
	ItemPtr item = GetItem(pChr, model_id);
	if(item.isNull())
		return 0;
	
	return item->getUInt32Field("value");
}

//-----------------------------------------------------------------------
uint64 GameLogicManager::GetBankerNum(CharPtr & chr, const uint32 model_id)
{ 
	return sBankMgr.GetCenterBankWealth(chr, model_id);
}

//-----------------------------------------------------------------------
uint64 GameLogicManager::GetAllNum(CharPtr & chr, const uint32 model_id)
{
	return GetItemTotalNum(chr, model_id) + GetBankerNum(chr, model_id);
}

uint32 GameLogicManager::resetCogealItemNum(CharPtr & pChr, const uint32 & model_id, bool isUpdate)
{
	ItemPtr item = GetItem(pChr, model_id);
	if(item.isNull())
		return 0;
	
	uint32 allnum = item->getUInt32Field("num") + item->getUInt32Field("value");
	item->setUInt32Field("num", allnum);
	item->setUInt32Field("value", 0);
	
	if (isUpdate)
	{
		ResourcePtr socket = pChr->getSocket();
		if(!socket.isNull())
		{		
			WorldPacket newP;
			if(sProtocolsMgr.CreateUpdateItemNumberPacket(&newP, model_id, allnum))
				SendPacket(socket, &newP);
		}
	}
	
	item->SaveDB();
	UpdateAboutMoney(pChr, model_id, allnum);
	return allnum;
}

//-----------------------------------------------------------------------
bool 	GameLogicManager::SendAddItemMessage(CharPtr & chr, const uint32 & model_id, const uint32 & number, const String & szType)
{
	if(chr.isNull() || !number)
		return false;
	
	ItemModelPtr model = sItemModelMgr.getByHandle(model_id);
	if(model.isNull())
		return false;
	
	String name = model->getStringField("name");
	if(name == "")
		return false;
	
	char str[512] = "";
	sprintf(str, sMsg.getMessage("gain_bounty").c_str(), sMsg.getMessage(szType).c_str(), number, name.c_str());
	SendSystemMessage(chr, str, sMsg.getType("gain_bounty"));	
	return true;
}

//-----------------------------------------------------------------------
bool 	GameLogicManager::SendReduceItemMessage(CharPtr & chr, const uint32 & model_id, const uint32 & number, const String & szType)
{
	if(chr.isNull() || !number)
		return false;
	
	ItemModelPtr model = sItemModelMgr.getByHandle(model_id);
	if(model.isNull())
		return false;
	
	String name = model->getStringField("name");
	if(name == "")
		return false;
	
	char str[200] = "";
	sprintf(str, sMsg.getMessage("reduce_item").c_str(), sMsg.getMessage(szType).c_str(), number, name.c_str());
	SendSystemMessage(chr, str, sMsg.getType("reduce_item"));	
	return true;
}

//-----------------------------------------------------------------------
ItemPtr GameLogicManager::GetItem(CharPtr & chr, const uint32 & model_id)
{
	ItemPtr item;
	if(chr.isNull() || model_id == 0)
		return item;
	
	std::list<ItemPtr> items;
	chr->getItemsList(&items);
	std::list<ItemPtr>::iterator ii, endii = items.end();
	for(ii = items.begin(); ii != endii; ++ii)
	{
		if((*ii)->model->getHandle() == model_id)
		{
			item = *ii;
			return item;
		}
	}
	
	return item;
}

//-----------------------------------------------------------------------
uint32 GameLogicManager::GetItemNum(CharPtr & chr, const uint32 & model_id)
{
	ItemPtr item = GetItem(chr, model_id);
	if(item.isNull())
	{
		return 0;
	}
		
	return item->getUInt32Field("num");
}
//-----------------------------------------------------------------------
uint32 GameLogicManager::GetItemTotalNum(CharPtr & chr, const uint32 & model_id)
{
	ItemPtr item = GetItem(chr, model_id);
	if(item.isNull())
	{
		return 0;
	}
		
	return item->getUInt32Field("num") + item->getUInt32Field("value");
}


//-----------------------------------------------------------------------
void 	GameLogicManager::SendPacket(ResourcePtr & socket, WorldPacket * newP)
{
	if(socket.isNull() || newP == NULL)
		return;
	
	if(socket->getType() == ResourceTypeWorldSocket)
	{
		WSSocketPtr soc = (WSSocketPtr)socket;
		soc->SendPacket(newP);
	}
}
//-----------------------------------------------------------------------
void GameLogicManager::SendProtocolsToChr(CharPtr & pChr, WorldPacket * packet)
{
	if (pChr.isNull() || NULL == packet)
		return;
	WSSocketPtr socket = pChr->getSocket();
	if(!socket.isNull())
		socket->SendPacket(packet);
}

void GameLogicManager::SendProtocolsToChrByPidGzid(const uint32 & pid, const uint32 & gz_id, WorldPacket * packet)
{
	if(!pid || !gz_id || NULL == packet)
		return ;
	
	Log.Debug("GameLogicManager::SendProtocolsToChrByPidGzid","pid[%u] gz_id[%u] 111", pid, gz_id);
	std::list<ResourcePtr> lstUser;
	sUserMgr.getDBObjects(&lstUser, 0, 1, " platform_id = %u and gz_id = %u", pid, gz_id);
	if(lstUser.empty())
		return ;
	
	Log.Debug("GameLogicManager::SendProtocolsToChrByPidGzid","pid[%u] gz_id[%u] 222", pid, gz_id);
	UserPtr pUser = sUserMgr.getByHandle((*lstUser.begin())->getUInt32Field("uid"));
	if(pUser.isNull())
		return ;
	
	Log.Debug("GameLogicManager::SendProtocolsToChrByPidGzid","pid[%u] gz_id[%u] 333", pid, gz_id);
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if(pChr.isNull())
		return ;
	
	Log.Debug("GameLogicManager::SendProtocolsToChrByPidGzid","pid[%u] gz_id[%u] 444", pid, gz_id);
	WSSocketPtr socket = pChr->getSocket();
	if(!socket.isNull())
		socket->SendPacket(packet);
}

//-----------------------------------------------------------------------
bool GameLogicManager::SendSystemMessage(CharPtr & chr, const char* pStr, const uint8 & type)
{
	if(!pStr || String(pStr) == "")
		return false;

	ResourcePtr socket = chr->getSocket();
	if(socket.isNull())
		return false;
	
	WorldPacket newP;
	if(sProtocolsMgr.CreateLocalMessagePacket(&newP, pStr, type))
		SendPacket(socket, &newP);
	
	return true;
}

//-----------------------------------------------------------------------
EffectPtr GameLogicManager::AddEffect(ResourceProxy owner, 
									const uint32 & model_id, 
									const uint32 & begin_time,
									const uint32 & data1 /* = 0 */, 
									const uint32 & data2 /* = 0 */, 
									const uint32 & data3 /* = 0 */, 
									const uint32 & data4 /* = 0 */,
									const float & fdata1 /* = 0.0f */,
									const float & fdata2 /* = 0.0f */)
{
	EffectPtr effectPtr;
	if(owner.isNull() || !model_id)
		return effectPtr;
	
	if(owner._type == ResourceTypeItem)
	{
		ItemPtr item = owner.getResourcePtr();
		if(item.isNull())
			return effectPtr;
		
		std::list<EffectPtr> effects;
		item->getEffectsList(&effects);
		std::list<EffectPtr>::iterator ei = effects.begin(), endei = effects.end();
		while(ei != endei)
		{
			if((*ei)->model->getHandle() == model_id)
				return *ei;			
				
			++ ei;
		}
	}
	else if(owner._type == ResourceTypeCharacter)
	{
		CharPtr chr = owner.getResourcePtr();
		if(chr.isNull())
			return effectPtr;
	}
	
	ResourcePtr modelPtr = sEffectModelMgr.load(model_id);
	if(modelPtr.isNull())
		return effectPtr;

	Resource * pEffect =  sEffectMgr.newDumyEffect();
	assert(pEffect);
	
	pEffect->setUInt32Field("effect_model_id", model_id);
	pEffect->setUInt32Field("status", Effect::EffectStatusProcess);
	pEffect->setUInt32Field("owner_type", owner.getTargetType());
	pEffect->setUInt32Field("owner_id", owner._handle);
	pEffect->setUInt32Field("effect_type", Effect::EffectStatusProcess);
	
	pEffect->setInt32Field("data1", (int32)data1);
	pEffect->setInt32Field("data2", (int32)data2);
	pEffect->setInt32Field("data3", (int32)data3);
	pEffect->setInt32Field("data4", (int32)data4);
	
	pEffect->setFloatField("fdata1", fdata1);
	pEffect->setFloatField("fdata2", fdata2);
	
	pEffect->setUInt32Field("start_time", begin_time);	
	uint32 duration = uint32(modelPtr->getUInt32Field("duration_time") / 1000);
	
	if(duration)
		pEffect->setUInt32Field("end_time", begin_time + duration);
		
	effectPtr = sEffectMgr.createEffectDatabase(pEffect);
	if(!effectPtr.isNull())
		effectPtr->load();
	
	sEffectMgr.freeDumyEffect(pEffect);
	
	return effectPtr;
}

//-----------------------------------------------------------------------
EffectPtr GameLogicManager::GetEffect(ResourceProxy owner, const uint32 & model_id)
{
	EffectPtr effect;
	if(owner._type == ResourceTypeCharacter)
	{
		CharPtr chr = owner.getResourcePtr();
		if(!chr.isNull())
		{
			std::list<EffectPtr> effects;
			chr->getEffectsList(&effects);
			std::list<EffectPtr>::iterator ii, endii = effects.end();
			for(ii = effects.begin(); ii != endii; ++ ii)
			{
				if((*ii)->model->getHandle() == model_id)
					return *ii;
			}
		}
	}
	
	return effect;
}

//-----------------------------------------------------------------------
MissionPtr GameLogicManager::AddMission(CharPtr &pChr, 
									const uint32 & model_id, 
									const uint32 & start_time,
									const uint32 & data1 /* = 0 */, 
									const uint32 & data2 /* = 0 */, 
									const uint32 & data3 /* = 0 */, 
									const uint32 & data4 /* = 0 */)
{
	
	MissionPtr missionPtr;
	if(pChr.isNull() || !model_id || pChr->isNPC())
		return missionPtr;
	
	std::list<MissionPtr> missions;
	pChr->getMissionsList(&missions);
	std::list<MissionPtr>::iterator iter, enditer = missions.end();
	for (iter = missions.begin(); iter != enditer; ++ iter)
	{
		MissionPtr pMission = *iter;
		if (pMission->getUInt32Field("mission_model_id") == model_id)
			return pMission;
	}
	
	ResourcePtr modelPtr = sMissionModelMgr.load(model_id);
	if(modelPtr.isNull())
		return missionPtr;
	Resource * pMission =  sMissionMgr.newDumyMission(model_id);
	pMission->setUInt32Field("mission_model_id", model_id);
	pMission->setUInt32Field("status", Mission::MissionStatusProcess);
	pMission->setUInt32Field("owner_type", pChr->getTargetType());
	pMission->setUInt32Field("owner_id", pChr->getHandle());

	pMission->setInt32Field("data1", (int32)data1);
	pMission->setInt32Field("data2", (int32)data2);
	pMission->setInt32Field("data3", (int32)data3);
	pMission->setInt32Field("data4", (int32)data4);
		
	pMission->setUInt32Field("start_time", start_time);	
	missionPtr = sMissionMgr.createMissionDatabase(pMission);
	if(!missionPtr.isNull())
		missionPtr->load();	
	sMissionMgr.freeDumyMission(pMission);
	
	return missionPtr;
}
//-----------------------------------------------------------------------
MissionPtr GameLogicManager::GetMission(CharPtr &pChr, const uint32 & model_id)
{
	std::list<MissionPtr> missions;
	pChr->getMissionsList(&missions);
	std::list<MissionPtr>::iterator iter, enditer = missions.end();
	for (iter = missions.begin(); iter != enditer; ++ iter)
	{
		MissionPtr pMission = *iter;
		if (pMission->getUInt32Field("mission_model_id") == model_id)
			return pMission;
	}
	MissionPtr missionPtr;
	return missionPtr;
}
//-----------------------------------------------------------------------
void GameLogicManager::Broadcast(WorldPacket &packet, std::vector<CharPtr> &vecChars, const uint8 exceptSeat)
{
	uint32 count = 0;
	std::vector<CharPtr>::iterator iter = vecChars.begin(), iterEnd = vecChars.end();
	for (; iter != iterEnd; ++iter)
	{
		if (exceptSeat == ++count)
			continue;
		ResourcePtr socket = (*iter)->getSocket();
		if (!socket.isNull())
			SendPacket(socket, &packet);
	}
}

//-----------------------------------------------------------------------
//发送给所有在线玩家
void GameLogicManager::BroadcastToAllUsers(WorldPacket &packet)
{
	std::list<ResourcePtr> sock_list;
	sWSSocketMgr.getSocketList(sock_list);
	if(sock_list.empty())
		return;
	
	std::list<ResourcePtr>::iterator iter,ei = sock_list.end();
	for(iter = sock_list.begin(); iter != ei; ++iter)
	{
		WSSocketPtr socket = (*iter);
		if(socket.isNull() || socket->m_Char.isNull())
			continue;
		CharPtr pChr = socket->getCurrentCharacter();
		if (pChr.isNull())
			continue;
		
		socket->SendPacket(&packet);
	}
}

//-----------------------------------------------------------------------
bool GameLogicManager::SendSysDebugMessage(CharPtr & chr, const uint32 & cid, const String & szName)
{
	ResourcePtr socket = chr->getSocket();
	if(socket.isNull())
		return false;
	
	char str[250] = "";
	sprintf(str, sMsg.getMessage(szName).c_str(), cid, 0);
	
	WorldPacket newP;
	if(sProtocolsMgr.CreateLocalMessagePacket(&newP, str, 2))
		SendPacket(socket, &newP);
	
	return true;
}
//-----------------------------------------------------------------------
bool GameLogicManager::DisconnectUserSocket(ResourcePtr & socket)
{
	if(socket.isNull())
		return false;
	
	uint8 socket_type = socket->getType();
	if(socket_type == ResourceTypeWorldSocket)
	{
		WSSocketPtr ws_socket = socket;
		ws_socket->Disconnect();
	}
	
	return true;
}
//-----------------------------------------------------------------------
bool GameLogicManager::FilterChars(String str, String &outStr)
{
	if (str.length() <= 10)
	{
		outStr = str;
		return true;
	}
	
	outStr = "";
	size_t pos = 0;
	int count = 0;
	bool last_ch = false;
	while( pos < str.size())
	{
		if(last_ch)
		{
			if(count >=10)
			{
				outStr += "*";
				break;
			}
		}
		else
		{
			if(count >=9)
			{
				outStr += "*";
				break;
			}
		}
		String subStr = str.substr(pos,3);
		if(StringUtil::checkStringUTF8(subStr))
		{
			outStr += subStr;
			count += 2;
			pos += 3;
			last_ch = true;
		}
		else
		{
			outStr += str[pos];
			count += 1;
			pos += 1;
			last_ch = false;
		}
		
	}
	return true;
}


//-----------------------------------------------------------------------
/**
 * 清理DDZ游戏邮件：清理超过限制日期的已读邮件
 */
bool GameLogicManager::CleanAllMails()
{
	uint32 limitDays = sXmlDataMgr.GetConfXMLValue("MAIL_LIMITDAYS");
	return CharacterDatabase.WaitExecute("update `game_mails` set `status` = %u where `data1` = %u and `status` = %u and DATEDIFF(now(),"
									"FROM_UNIXTIME(`create_time`)) > %u;",
									Mail::MailStatusDeleted, sXmlDataMgr.GetConfXMLValue("GAME_ID"), Mail::MailStatusOpen, limitDays);
}
//-----------------------------------------------------------------------
/**
 * 清理个人邮箱，如果数量小于规定最大数量，不用清理，直接返回；否则，清理超过限制日期的已读邮件；如果没有可供清理的已读邮件，则清理时间最早的若干邮件
 */
bool GameLogicManager::CleanUserMails(const uint32 userId)
{
	// 个人邮件最大数量
	uint32 maxNumber = sXmlDataMgr.GetConfXMLValue("MAIL_MAXNUM");
	uint32 mailNum = sChannelMgr.getMailDBCount("`recv_serial` = %u", userId);
	if (mailNum < maxNumber)
		return true;
	std::list<GameMail> lstMails;
	// 已读邮件清理限制日期
	uint32 limitDays = sXmlDataMgr.GetConfXMLValue("MAIL_LIMITDAYS");
	if (!sChannelMgr.getMailList(&lstMails, 0, mailNum, "`recv_serial` = %u and `status` = %u and DATEDIFF(now(),FROM_UNIXTIME(`create_time`)) > %u", 
		userId, Mail::MailStatusOpen, limitDays))
		return false;
	if (lstMails.size() > 0)
	{
		std::list<GameMail>::iterator iter(lstMails.begin());
		for (; iter != lstMails.end(); ++iter)
		{
			(*iter).status = Mail::MailStatusDeleted;
			sChannelMgr.updateMailDB(&(*iter));
		}
	}
	else
	{
		// 个人邮件限制数量
		uint32 limitNumber = sXmlDataMgr.GetConfXMLValue("MAIL_LIMITNUM"); 
		lstMails.clear();
		if (!sChannelMgr.getMailList(&lstMails, limitNumber, mailNum, "`recv_serial` = %u order by `create_time` desc", userId))
			return false;
		std::list<GameMail>::iterator iter(lstMails.begin());
		for (; iter != lstMails.end(); ++iter)
		{
			(*iter).status = Mail::MailStatusDeleted;
			sChannelMgr.updateMailDB(&(*iter));
		}
	}
	return true;
}

// 检测过期邮件，调用在CleanUserMails前面，因为里面对过期邮件的处理方式有不同
bool GameLogicManager::CheckExpireMails(const uint32 & pid,const uint32 & gz_id)
{
	if(!pid || !gz_id)
		return false;
	
	std::list<UserPtr> lstUser;
	sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u AND `gz_id`=%u", pid, gz_id);
	if (lstUser.empty())
		return false;
	UserPtr pUser = lstUser.front();
	if (pUser.isNull())
		return false;
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if(pChr.isNull())
	{
		pChr = sCharMgr.load(pUser->getUInt32Field("char_id"));
		if(pChr.isNull())
			return false;
	}
	uint32 time_now = time(0);
	// 过期了的邮件数量
	uint32 expireNum = sChannelMgr.getMailDBCount("`recv_serial` = %u and `expiration_time` > 0 and `expiration_time` < %u and `status` < 255", pid,time_now);
	if (expireNum == 0)	// 没有过期邮件
		return true;
	std::list<GameMail> lstMails;
	// 已读邮件清理限制日期
	if (!sChannelMgr.getMailList(&lstMails, 0, expireNum, "`recv_serial` = %u and `expiration_time` > 0 and `expiration_time` < %u and `status` < 255", pid, time_now))
		return false;
	if (lstMails.size())
	{
		std::list<GameMail>::iterator iter = lstMails.begin();
		for (; iter != lstMails.end(); ++iter)
		{
			if((*iter).data1 && (*iter).data3 == 0)	//有附件未领
			{
				Json::Reader reader;
				Json::Value val;
				reader.parse((*iter).contenct, val);
				
				if(val.isMember("items"))
				{
					for (Json::Value::iterator iterV=val["items"].begin(); iterV!=val["items"].end(); ++iterV)
					{
						uint32 model_id = StringConverter::parseUnsignedInt(iterV.key().asString());
						uint32 num = (*iterV).asUInt();
						
						sGLMgr.addItemNum(pChr, model_id, num);
						sLogDataMgr.UpdateItemsInfoLog(pChr, SourceType((*iter).data2), model_id, en_UNT_Add, num);
					}
				}
				
				Log.Debug("GameLogicManager::CheckExpireMails","pid[%u] char mails timeover autoget items!",pid);
			}
			
			(*iter).status = Mail::MailStatusDeleted;
			sChannelMgr.updateMailDB(&(*iter));
		}
	}
	
	return true;
}

// 领取邮件附件
uint8 GameLogicManager::GetMailItems(CharPtr & pChr,const uint32 & mailId)
{
	if(pChr.isNull() || mailId == 0)
		return en_OperatorMailResult_NoMail;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return en_OperatorMailResult_NoMail;
	
	GameMail pMail;
	sChannelMgr.getMailDB(mailId, &pMail);
	if (pMail.mail_id == 0)
		return en_OperatorMailResult_NoMail;
	
	// 检测邮件是否属于自己
	if(pMail.recv_serial != pUser->getUInt32Field("platform_id"))
		return en_OperatorMailResult_NoMail;
	
	// 无附件邮件
	if(pMail.data1 == 0)
		return en_OperatorMailResult_NoItems;
	
	// 附件已经领取
	if(pMail.data3 == 1)
		return en_OperatorMailResult_ItemsAreadyGet;
	
	// 遍历物品json，记录对应日志
	Json::Reader reader;
	Json::Value val;
	reader.parse(pMail.contenct, val);
	
	if(val.isMember("items"))
	{
		for (Json::Value::iterator iter=val["items"].begin(); iter!=val["items"].end(); ++iter)
		{
			uint32 model_id = StringConverter::parseUnsignedInt(iter.key().asString());
			uint32 num = (*iter).asUInt();
			
			sGLMgr.addItemNum(pChr, model_id, num);
			sLogDataMgr.UpdateItemsInfoLog(pChr, SourceType(pMail.data2), model_id, en_UNT_Add, num);
		}
	}
	
	pMail.data3 = 1;							// 更新领取状态
	if(pMail.status != Mail::MailStatusOpen)	// 未读置为已读
		pMail.status = Mail::MailStatusOpen;
	
	sChannelMgr.updateMailDB(&pMail);
	
	return en_OperatorMailResult_Successed;
}

// 领取全服邮件
uint8 GameLogicManager::GetAllServerMailItems(CharPtr & pChr,const uint32 & mailId)
{
	if(pChr.isNull())
		return en_OperatorMailResult_NoMail;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
	{
		pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
		if(pUser.isNull())
			return en_OperatorMailResult_NoMail;
	}
	
	GameMail pMail;
	sChannelMgr.getMailDB(mailId, &pMail);
	if(pMail.mail_id == 0)
		return en_OperatorMailResult_NoMail;
	
	// 类型不对
	if(pMail.send_type != en_MailSendType_AllServer)
		return en_OperatorMailResult_NoMail;
	
	// 分区不对
	if(pMail.send_serial != pChr->getUInt32Field("gz_id"))
		return en_OperatorMailResult_NoMail;
	
	// 无附件邮件
	if(pMail.data1 == 0)
		return en_OperatorMailResult_NoMail;
	
	// 邮件过期
	if(pMail.expiration_time <= time(0))
		return en_OperatorMailResult_NoMail;
	
	// 判断全服邮件是否已经领取 将玩家领取邮件的结果存入银行数据中
	GameBank pBank;
	sBankMgr.GetPublicData(pUser,&pBank);
	if(pBank.bank_id == 0)
		return en_OperatorMailResult_NoMail;
	
	Json::Value json_mailTime = sBankMgr.GetUserDataJson(pBank,"MAILTIME");
	for(Json::Value::iterator it=json_mailTime.begin(); it!=json_mailTime.end(); ++it)
	{
		uint32 mail_id = StringConverter::parseUnsignedInt(it.key().asString());
		if(mailId == mail_id)
			return en_OperatorMailResult_ItemsAreadyGet;	//领取过
	}
	
	Json::Value json_content,new_json_mailTime;
	Json::Reader reader;
	reader.parse(pMail.contenct, json_content);
	
	if(json_content.isMember("items"))
	{
		for (Json::Value::iterator iter=json_content["items"].begin(); iter!=json_content["items"].end(); ++iter)
		{
			uint32 model_id = StringConverter::parseUnsignedInt(iter.key().asString());
			uint32 num = (*iter).asUInt();
			
			sGLMgr.addItemNum(pChr, model_id, num);
			sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_SystemBuZhu, model_id, en_UNT_Add, num);
		}
	}
	
	uint32 time_now = time(0);
	bool bUpdateJson = false;
	
	json_mailTime[StringConverter::toString(mailId).c_str()] = uint32(time_now);
	if(json_mailTime.size() >= 30)
	{
		for(Json::Value::iterator it=json_mailTime.begin(); it!=json_mailTime.end(); ++it)
		{
			uint32 mail_id = StringConverter::parseUnsignedInt(it.key().asString());
			GameMail pMail;
			sChannelMgr.getMailDB(mail_id, &pMail);
			
			// 清除一些过期邮件的ID领取时间
			if(pMail.mail_id != 0)
			{
				if(pMail.status == 255 || pMail.expiration_time <= time_now)
				{
					bUpdateJson = true;
					continue;
				}
			}
			
			new_json_mailTime[it.key().asString().c_str()] = (*it).asUInt();;
		}
	}
	
	Json::FastWriter w;
	if(bUpdateJson)
		sBankMgr.SetUserDataJson(pBank,"MAILTIME",new_json_mailTime);
	else
		sBankMgr.SetUserDataJson(pBank,"MAILTIME",json_mailTime);
	
	sBankMgr.SaveUserDataDB(pBank);
	return en_OperatorMailResult_Successed;
}

// 领取所有邮件附件
uint8 GameLogicManager::GetAllMailsItems(CharPtr & pChr)
{
	if(pChr.isNull())
		return en_OperatorMailResult_NoMail;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return en_OperatorMailResult_NoMail;
	
	uint32 pid = pUser->getUInt32Field("platform_id");
	
	uint32 time_now = time(0);
	std::list<GameMail> lstMails;
	uint32 haveItemMails = sChannelMgr.getMailDBCount("(`recv_serial` = %u and `data1` = 1 and `data3` = 0) or \
									(`send_serial` = %u and `send_type` = %u and (`expiration_time` > %u or  `expiration_time` = 0) and `create_time` < %u)", 
									pid,pChr->getUInt32Field("gz_id"),en_MailSendType_AllServer,
									time_now,pUser->getUInt32Field("reg_time"));
	
	if (haveItemMails)	// 有邮件
	{
		if (!sChannelMgr.getMailList(&lstMails, 0, haveItemMails, "`recv_serial` = %u and `data1` = 1 and `data3` = 0", pid))
			return en_OperatorMailResult_NoMail;
		
		std::list<GameMail>::iterator iter,ei = lstMails.end();
		for(iter = lstMails.begin(); iter!=ei; ++iter)
		{
			if((*iter).send_type == en_MailSendType_AllServer)
				GetAllServerMailItems(pChr,(*iter).mail_id);
			else
				GetMailItems(pChr,(*iter).mail_id);
		}
	}
	
	return en_OperatorMailResult_Successed;
}

uint8 GameLogicManager::ReadAllMails(CharPtr & pChr)
{
	if(pChr.isNull())
		return en_OperatorMailResult_NoMail;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return en_OperatorMailResult_NoMail;
	
	uint32 pid = pUser->getUInt32Field("platform_id");
	
	uint32 db_count = sChannelMgr.getMailDBCount("`recv_serial` = %u and `status` = %u", pid, Mail::MailStatusRecv);
	
	std::list<GameMail> lstMails;
	sChannelMgr.getMailList(&lstMails, 0, db_count, "`recv_serial` = %u and `status` = %u", pid, Mail::MailStatusRecv);
	if(lstMails.empty())
		return en_OperatorMailResult_NoMail;
	
	std::list<GameMail>::iterator iter, ei=lstMails.end();
	for(iter = lstMails.begin(); iter!=ei; ++iter)
	{// 标记已读，更新
		(*iter).status = Mail::MailStatusOpen;
		sChannelMgr.updateMailDB(&(*iter));
	}
	
	return en_OperatorMailResult_Successed;
}

uint8 GameLogicManager::DeleteMail(CharPtr & pChr, const uint32 & mail_id)
{
	if(pChr.isNull())
		return en_OperatorMailResult_NoMail;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return en_OperatorMailResult_NoMail;
	
	uint32 pid = pUser->getUInt32Field("platform_id");
	
	GameMail pMail;
	sChannelMgr.getMailDB(mail_id, &pMail);
	
	if(pMail.recv_serial != pid)
		return en_OperatorMailResult_NoMail;
	
	// 更改为已读状态
	if (pMail.status != Mail::MailStatusDeleted)
	{
		// 尝试领取附件
		GetMailItems(pChr, mail_id);
		
		if(pMail.send_type != en_MailSendType_AllServer)
		{// 非全服邮件类型，更新邮件状态
			pMail.status = Mail::MailStatusDeleted;
			sChannelMgr.updateMailDB(&pMail);
		}
	}
	
	return en_OperatorMailResult_Successed;
}

//-----------------------------------------------------------------------
void GameLogicManager::Pwd2LockedMessage(UserPtr &pUser, const uint32 leftTime)
{
	if (pUser.isNull())
		return;
	WSSocketPtr socket = pUser->m_Socket.getResourcePtr();
	if (socket.isNull())
		return;
	char buf[256];
	memset(buf, 0, sizeof(buf));
	sprintf(buf, sMsg.getMessage("pwd2locked").c_str(), leftTime);
	WorldPacket packet;
	if (sProtocolsMgr.CreateLocalMessagePacket(&packet, buf, sMsg.getType("pwd2locked")))
		socket->SendPacket(&packet);
}

//-----------------------------------------------------------------------
void GameLogicManager::LewdLockedMessage(UserPtr &pUser, const uint32 leftTime)
{
	if (pUser.isNull())
		return;
	WSSocketPtr socket = pUser->m_Socket.getResourcePtr();
	if (socket.isNull())
		return;
	char buf[256];
	memset(buf, 0, sizeof(buf));
	sprintf(buf, sMsg.getMessage("lewdlocked").c_str(), leftTime);
	WorldPacket packet;
	if (sProtocolsMgr.CreateLocalMessagePacket(&packet, buf, sMsg.getType("lewdlocked")))
		socket->SendPacket(&packet);
}

//-----------------------------------------------------------------------
void GameLogicManager::LoginWellcomeMessage(UserPtr &pUser)
{
	if (pUser.isNull())
		return;
	WSSocketPtr socket = pUser->m_Socket.getResourcePtr();
	if (socket.isNull())
		return;
	char buf[256];
	memset(buf, 0, sizeof(buf));
	sprintf(buf, sMsg.getMessage("loginwellcome").c_str(), GetCurDateTime(pUser->getUInt32Field("ll_time")).c_str());
	WorldPacket packet;
	if (sProtocolsMgr.CreateLocalMessagePacket(&packet, buf, sMsg.getType("loginwellcome")))
		socket->SendPacket(&packet);
}
//-----------------------------------------------------------------------
uint8 GameLogicManager::CkExchageTicket(CharPtr &pChr, String &ticket)
{
	if (pChr.isNull())
		return 0;
	String strMsg;
	GameExchange gexc;
	
	ticket = CharacterDatabase.EscapeString(ticket);
	// 兑换卡是否存在
	if (!sItemMgr.getExchangeDB(ticket, &gexc)) 
		return en_ExchangeResult_TicketNotExisited;
	// 兑换卡是否过期
	if (GetDateTimeSeconds(gexc.end_time) < time(0))
		return en_ExchangeResult_TicketOverdue;
	// 兑换卡是否已经被兑换过
	if (gexc.status == 2) 
		return en_ExchangeResult_TicketExchanged;
	if (gexc.item_model1 > 0)
	{
		addItemNum(pChr, gexc.item_model1, gexc.item_num1);
		strMsg += StringConverter::toString(gexc.item_num1);
		strMsg += "x";
		strMsg += gexc.item_name1;
		strMsg += " ";
		// 记录日志
		sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Exchange, gexc.item_model1, en_UNT_Add, gexc.item_num1, gexc.exchange_id);
	}
	if (gexc.item_model2 > 0)
	{
		addItemNum(pChr, gexc.item_model2, gexc.item_num2);
		strMsg += StringConverter::toString(gexc.item_num2);
		strMsg += "x";
		strMsg += gexc.item_name2;
		strMsg += " ";
		// 记录日志
		sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Exchange, gexc.item_model2, en_UNT_Add, gexc.item_num2, gexc.exchange_id);
	}
	if (gexc.item_model3 > 0)
	{
		addItemNum(pChr, gexc.item_model3, gexc.item_num3);
		strMsg += StringConverter::toString(gexc.item_num3);
		strMsg += "x";
		strMsg += gexc.item_name3;
		strMsg += " ";
		// 记录日志
		sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Exchange, gexc.item_model3, en_UNT_Add, gexc.item_num3, gexc.exchange_id);
	}
	if (gexc.item_model4 > 0)
	{
		addItemNum(pChr, gexc.item_model4, gexc.item_num4);
		strMsg += StringConverter::toString(gexc.item_num4);
		strMsg += "x";
		strMsg += gexc.item_name4;
		// 记录日志
		sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Exchange, gexc.item_model4, en_UNT_Add, gexc.item_num4, gexc.exchange_id);
	}
	// 发送系统消息
	WSSocketPtr socket = pChr->getSocket();
	if (!socket.isNull())
	{
		WorldPacket packet;
		if (sProtocolsMgr.CreateLocalMessagePacket(&packet, sMsg.getMessage("changesucceed") + strMsg, sMsg.getType("changesucceed")))
			socket->SendPacket(&packet);
	}
	// 更新兑换相关数据
	gexc.status = 2;
	gexc.token_user = pChr->getUInt32Field("userid");
	gexc.token_time = GetCurDateTime();
	sItemMgr.updateExchangeDB(&gexc);
	return en_ExchangeResult_Success;
}
//-----------------------------------------------------------------------
void GameLogicManager::WholeServerBroadcast(WorldPacket *pPacket, const uint32 gzId)
{
	if (NULL == pPacket)
		return;
	std::list<ResourcePtr> sock_list;
	sWSSocketMgr.getSocketList(sock_list);
	if(sock_list.empty())
		return;
	std::list<ResourcePtr>::iterator iter,ei = sock_list.end();
	for(iter = sock_list.begin(); iter != ei; ++iter)
	{
		WSSocketPtr socket = (*iter);
		if(socket.isNull() || socket->m_Char.isNull())
			continue;
		CharPtr pChr = socket->getCurrentCharacter();
		if (pChr.isNull())
			continue;
		if (gzId > 0)
		{
			if (pChr->getUInt32Field("gz_id") != gzId)
				continue;
		}
		socket->SendPacket(pPacket);
	}
}

//-----------------------------------------------------------------------
void GameLogicManager::BroadcastEx(WorldPacket * pPacket, const uint32 & town_type, const uint32 & gz_id)
{
	if (NULL == pPacket)
		return;
	std::list<ResourcePtr> sock_list;
	sWSSocketMgr.getSocketList(sock_list);
	if(sock_list.empty())
		return;
	std::list<ResourcePtr>::iterator iter,ei = sock_list.end();
	for(iter = sock_list.begin(); iter != ei; ++iter)
	{
		WSSocketPtr socket = (*iter);
		if(socket.isNull() || socket->m_Char.isNull())
			continue;
			
		CharPtr pChr = socket->getCurrentCharacter();
		if (pChr.isNull())
			continue;
		
		if(gz_id && pChr->getUInt32Field("gz_id") != gz_id)
			continue;
		
		AICreatureBaseInterface * pAWCI = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
		if(pAWCI)
		{
			if(town_type == 0)
			{
				socket->SendPacket(pPacket);
			}
			else
			{
				TownPtr pTown = pAWCI->GetTown();
				if(pTown.isNull() || pTown->getUInt32Field("type") == town_type)
				{
					socket->SendPacket(pPacket);
				}				
			}
		}
	}
}

//-----------------------------------------------------------------------
void 	GameLogicManager::BroadcastByTownID(WorldPacket * pPacket, const uint32 & handle, const uint32 & excSerial)
{
	if (NULL == pPacket)
		return;
	std::list<ResourcePtr> sock_list;
	sWSSocketMgr.getSocketList(sock_list);
	if(sock_list.empty())
		return;
	std::list<ResourcePtr>::iterator iter,ei = sock_list.end();
	for(iter = sock_list.begin(); iter != ei; ++iter)
	{
		if ((*iter)->getHandle() == excSerial)
			continue;
		WSSocketPtr socket = (*iter);
		if(socket.isNull() || socket->m_Char.isNull())
			continue;
		CharPtr pChr = socket->getCurrentCharacter();
		if (pChr.isNull())
			continue;
		
		AICreatureBaseInterface * pAWCI = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
		if(pAWCI)
		{
			TownPtr pTown = pAWCI->GetTown();
			if(!pTown.isNull() && pTown->getHandle() == handle)
			{
				socket->SendPacket(pPacket);
			}
		}
	}
}

//-----------------------------------------------------------------------
void 	GameLogicManager::BroadcastByGZID(WorldPacket * pPacket, const uint32 & gz_id)
{
	if (NULL == pPacket)
		return;
	std::list<ResourcePtr> sock_list;
	sWSSocketMgr.getSocketList(sock_list);
	if(sock_list.empty())
		return;
	std::list<ResourcePtr>::iterator iter,ei = sock_list.end();
	for(iter = sock_list.begin(); iter != ei; ++iter)
	{
		WSSocketPtr socket = (*iter);
		if(socket.isNull() || socket->m_Char.isNull())
			continue;
		CharPtr pChr = socket->getCurrentCharacter();
		if (pChr.isNull())
			continue;
		
		if(pChr->getUInt32Field("gz_id") == gz_id)
		{
			socket->SendPacket(pPacket);
		}
	}
}

//-----------------------------------------------------------------------
void 	GameLogicManager::BroadcastByFromID(WorldPacket * pPacket, const uint32 & from_id, const uint8 & send_player_flag)
{
	if (NULL == pPacket)
		return;
	std::list<ResourcePtr> sock_list;
	sWSSocketMgr.getSocketList(sock_list);
	if(sock_list.empty())
		return;
	std::list<ResourcePtr>::iterator iter,ei = sock_list.end();
	for(iter = sock_list.begin(); iter != ei; ++iter)
	{
		WSSocketPtr socket = (*iter);
		if(socket.isNull() || socket->m_Char.isNull())
			continue;
		CharPtr pChr = socket->getCurrentCharacter();
		if (pChr.isNull())
			continue;
		
		UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
		if(pUser.isNull())
			continue;
		
		// 是否限制regfrom
		bool enable = sXmlDataMgr.GetConfXMLValue("ENABLE_REGFROM");
		if(	enable == false || 
			pUser->getUInt32Field("reg_from") == from_id ||
			(pChr->getUInt32Field("flag") & en_CreatureFlag_BothMCount) )
		{
			if((send_player_flag & en_CreatureFlag_SendExceptQQGame) 
				&& (pUser->getUInt32Field("reg_from") == 1025))
			{// 发送给除了QQ游戏的其他平台
				continue;
			}
			
			socket->SendPacket(pPacket);
		}
	}
}

//-----------------------------------------------------------------------
void GameLogicManager::SendNotice(String &strMsg, const uint32 type, const uint32 gzId)
{
	WorldPacket packet;
	if(sProtocolsMgr.CreateLocalMessagePacket(&packet, strMsg, type))
		WholeServerBroadcast(&packet, gzId);
}
//-----------------------------------------------------------------------
void GameLogicManager::SendMsgToPlayer(const uint32 userId, String &strMsg, const uint32 type)
{
	WorldPacket packet;
	if(sProtocolsMgr.CreateLocalMessagePacket(&packet, strMsg, type))
	{
		UserPtr pUser = sUserMgr.getByHandle(userId);
		if (pUser.isNull())
			return;
		WSSocketPtr socket = pUser->m_Socket.getResourcePtr();
		if (socket.isNull())
			return;
		socket->SendPacket(&packet);
	}
}
//-----------------------------------------------------------------------
bool 	GameLogicManager::addCreatureTitle(CharPtr & pChr, EffectPtr & pEffect, bool isInstant)
{
	if(pChr.isNull() || pEffect.isNull())
		return false;
	
	if(pEffect->getUInt32Field("effect_type") != Effect::EffectStatusClose && 
		pEffect->getUInt32Field("effect_type") != en_EffectStatus_Sucess)
		return false;
	
	AICreatureBaseInterface * pAWCI = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(!pAWCI)	
		return false;
	
	pEffect->setUInt32Field("effect_type", Effect::EffectStatusError);
	pAWCI->addTitle(pEffect->model->getHandle());
	
	WSSocketPtr pSocket = pChr->getSocket();
	if(!pSocket.isNull())
	{
		WorldPacket newP;
		if(sProtocolsMgr.CreateNewTitlePacket(&newP, pEffect->model->getHandle()))
			pSocket->SendPacket(&newP);
	}
	
	if(isInstant)
	{
		uint32 item_num = pEffect->model->getUInt32Field("effect2");
		if(item_num)
		{
			SendTitleMessage(pChr, pEffect->model->getStringField("name"), ItemModel_Coins, item_num);
			addItemNum(pChr, ItemModel_Coins, item_num);
			sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Effort, ItemModel_Coins, en_UNT_Add, item_num, pEffect->model->getHandle());
		}
		pChr->SaveDB();
		Log.Debug("GameLogicManager Test", "addCreatureAllEffort pChr[%u] Effort[%u]", pChr->getHandle(), pEffect->model->getHandle());
		ResourceProxy proxy = (ResourcePtr)pEffect;
		sResourceControlMgr.destroyResource(proxy);
	}
	
	return true;
}

//-----------------------------------------------------------------------
void 	GameLogicManager::SendTitleMessage(CharPtr & pChr, const String & szName, const uint32 & itmodel, const uint32 & itnum)
{
	ItemModelPtr imodel = sItemModelMgr.getByHandle(itmodel);
	if(imodel.isNull())
		return ;
		
	char str[1024] = "";
	sprintf(str, sMsg.getMessage("gettitle").c_str(), szName.c_str(), itnum, imodel->getStringField("name").c_str());
	SendSystemMessage(pChr, str, sMsg.getType("gettitle"));
}

//-----------------------------------------------------------------------
String GameLogicManager::RvRpDBCharacter(String &str, bool bRemove)
{
	String ret = str;
	String::size_type pos;
	if (bRemove)
	{
		while((pos = ret.find('\'')) != String::npos)
		{
			ret.erase(pos,1);
		}
		while((pos = ret.find('\\')) != String::npos)
		{
			ret.erase(pos,1);
		}
		while((pos = ret.find(';')) != String::npos)
		{
			ret.erase(pos,1);
		}
		while((pos = ret.find(' ')) != String::npos)
		{
			ret.erase(pos,1);
		}
	}
	else
	{
		while((pos = ret.find('\'')) != String::npos)
		{
			ret.replace(pos, 1, 1, '.');
		}
		while((pos = ret.find('\\')) != String::npos)
		{
			ret.replace(pos, 1, 1, '.');
		}
		while((pos = ret.find(';')) != String::npos)
		{
			ret.replace(pos, 1, 1, '.');
		}
		while((pos = ret.find(' ')) != String::npos)
		{
			ret.replace(pos, 1, 1, '.');
		}
		while((pos = ret.find(' ')) != String::npos)
		{
			ret.replace(pos, 1, 1, '.');
		}
	}
	return ret;
}

//-----------------------------------------------------------------------
void 	GameLogicManager::addCreatureAllEffort(CharPtr & pChr)
{
	if(pChr.isNull() || pChr->isNPC())	
		return;
	
	if(pChr->getUInt32Field("effect"))
		return;
	
	ResourcePtr pRes = (ResourcePtr)pChr;
	
	std::list<ResourcePtr> effectmodels;
	sEffectModelMgr.getResourceList(&effectmodels);
	std::list<ResourcePtr>::iterator ei, endei = effectmodels.end();
	for(ei = effectmodels.begin(); ei != endei; ++ ei)
	{
		if((*ei)->getUInt32Field("type") == EffectType_Effort)
		{
			AddEffect(pRes, (*ei)->getHandle(), time(0));
		}
	}
	
	pChr->setUInt32Field("effect", effectmodels.size());
}

//-----------------------------------------------------------------------
void 	GameLogicManager::BuildCreatureAllEffortByJson(CharPtr & pChr)
{
	if (pChr.isNull() || pChr->isNPC())
		return;
	
	EffectModelPtr pLogicEff = sEffectModelMgr.getByHandle(en_EffectLogicModel_Achievement);
	if (pLogicEff.isNull())
		return;
	std::list<EffectPtr> lstMyEffort;
	pChr->getEffectsList(&lstMyEffort);
	std::list<EffectPtr>::iterator myIt, endmyIt = lstMyEffort.end();
	for (myIt = lstMyEffort.begin(); myIt != endmyIt; ++ myIt)
	{
		if ((*myIt)->getUInt32Field("effect_model_id") == en_EffectLogicModel_Achievement)
			return;
	}
	// 搜出所有效果
	std::list<EffectModelPtr> lstAchievements;
	std::list<ResourcePtr> lstEffectmodels;
	sEffectModelMgr.getResourceList(&lstEffectmodels);
	std::list<ResourcePtr>::iterator iter,enditer = lstEffectmodels.end();
	for (iter = lstEffectmodels.begin(); iter != enditer; ++ iter)
	{
		ResourcePtr pRes = *iter;
		if (pRes.isNull())
			continue;
		if (pRes->getUInt32Field("type") != EffectType_Effort)
			continue;
		lstAchievements.push_back(pRes);		
	}
	// 整理为Json
	// Json::StyledWriter styWriter;	
	Json::Value root;
	std::list<EffectModelPtr>::iterator ei, endei = lstAchievements.end();
	for (ei = lstAchievements.begin(); ei != endei; ++ ei)
	{
		EffectModelPtr pModel = *ei;
		Json::Value child;		
		child["id"] = Json::Value((uint32)pModel->getHandle());		
		child["num"] = Json::Value(0);
		child["finish_time"] = Json::Value(0);
		child["getbonus"] = Json::Value(0);
		root.append(child);
	}
	// 创建效果逻辑
	ResourceProxy owner = (ResourcePtr)pChr;
	EffectPtr pEff = sGLMgr.AddEffect(owner, en_EffectLogicModel_Achievement, time(0));
	if (pEff.isNull())
		return;
	Json::StyledWriter styWriter;
	pEff->setStringField("info", styWriter.write(root));
	pEff->SaveDB();
}

//-----------------------------------------------------------------------
void GameLogicManager::CompleteEffort(CharPtr & pChr, Effect * pEffect)
{
	if(pChr.isNull() || !pEffect)
		return;
	
	EffectPtr effectPtr = sEffectMgr.load(pEffect->getHandle());
	if(effectPtr.isNull())
		return ;
	
	if(effectPtr->getUInt32Field("effect_type") != en_EffectStatus_Process)
		return;
	
	effectPtr->setUInt32Field("effect_type",en_EffectStatus_Sucess);
	effectPtr->setUInt32Field("data1",effectPtr->model->getUInt32Field("effect1"));
	effectPtr->setUInt32Field("data3",time(0));
	effectPtr->SaveDB();
	
	AICreatureBaseInterface *pChrAiInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(!pChrAiInfe)	
		return ;
	
	uint32 effortId = effectPtr->model->getHandle();
	
	Log.Warning("GameLogicManager::CompleteEffort", "effect_model_id[%u] completed", effortId);
	// 下发产生新成就
	WorldPacket packet;
	if(sProtocolsMgr.CreateEffortInfoPacket(&packet,effectPtr))
		SendProtocolsToChr(pChr,&packet);
	
	// 消息(成就完成）
	char msg[256];
	sprintf(msg, sMsg.getMessage("effect_complete").c_str(), effectPtr->model->getStringField("name").c_str());
	SendSystemMessage(pChr, msg, sMsg.getType("effect_complete"));
	
	if(effectPtr->model->getUInt32Field("class") > 1)
	{
		sprintf(msg,sMsg.getMessage("finishhard_effort").c_str(),pChr->getCharName().c_str(),effectPtr->model->getStringField("name").c_str());
		sNoticeMgr.AddMsgToQueue(msg, 1);
	}
	
	// 完成成就
	ResourceEvent event;
	event.event_id = ResouceEvent_EffortStat;
	pChr->SendEvent(&event);
}

//-----------------------------------------------------------------------
bool GameLogicManager::addEffortPointByJson(EffectPtr &pEffLogic, const uint32 &effortId, const uint32 &addNum)
{
	if (pEffLogic.isNull())
		return false;
	CharPtr pChr = sCharMgr.getByHandle(pEffLogic->getUInt32Field("owner_id"));
	if (pChr.isNull())
		return false;
	WSSocketPtr pSocket = pChr->getSocket();	
	WorldPacket packet;
	String strJs = pEffLogic->getStringField("info");
	Json::Value root;
	Json::Reader reader;
	reader.parse(strJs, root);
	for (uint32 i=0; i!=root.size(); ++i)
	{
		Json::Value &child = root[i];
		uint32 modelId = child["id"].asUInt();
		if (modelId == effortId)
		{
			if (child["finish_time"].asUInt())
				return false;
			uint32 number = child["num"].asUInt() + addNum;
			child["num"] = Json::Value(number);
			// 判断是否完成成就
			EffectModelPtr pModel = sEffectModelMgr.getByHandle(modelId);
			if (number >= pModel->getUInt32Field("effect1"))
			{// 完成
				uint32 ntime = time(0);
				child["finish_time"] = Json::Value(ntime);
				if (!pSocket.isNull())
				{
					if (sProtocolsMgr.CreateNewTitlePacket(&packet, pModel->getHandle()))
						pSocket->SendPacket(&packet);
				}
			}
			else
			{
				if (!pSocket.isNull())
				{
					if (sProtocolsMgr.CreateUpdateEffortPacket(&packet, pModel->getHandle(), 2, number))
						pSocket->SendPacket(&packet);
				}
			}
			Json::StyledWriter styWriter;
			pEffLogic->setStringField("info", styWriter.write(root));
			pEffLogic->SaveDB();
			return true;
		}
	}
	
	return false;
}
//-----------------------------------------------------------------------
bool GameLogicManager::GetEffortBonusByJson(EffectPtr &pEffLogic, const uint32 &effortId)
{
	if (pEffLogic.isNull())
		return false;
	CharPtr pChr = sCharMgr.getByHandle(pEffLogic->getUInt32Field("owner_id"));
	if (pChr.isNull())
		return false;
	WSSocketPtr pSocket = pChr->getSocket();	
	WorldPacket packet;
	String strJs = pEffLogic->getStringField("info");
	Json::Value root;
	Json::Reader reader;
	reader.parse(strJs, root);
	for (uint32 i=0; i!=root.size(); ++i)
	{
		Json::Value &child = root[i];
		uint32 modelId = child["id"].asUInt();
		if (modelId == effortId)
		{
			if (!child["finish_time"].asUInt())
				return false;
			child["getbonus"] = Json::Value(1);			
			Json::StyledWriter styWriter;
			pEffLogic->setStringField("info", styWriter.write(root));
			pEffLogic->SaveDB();
			return true;
		}
	}
	return false;
}
//-----------------------------------------------------------------------
String 	GameLogicManager::GetItemName(const uint32 & model_id)
{
	ItemModelPtr model = sItemModelMgr.getByHandle(model_id);
	if(model.isNull())
		return "";
	
	return model->getStringField("name");
}

//-----------------------------------------------------------------------
void 	GameLogicManager::CombItemData(CharPtr & pChr)
{
	if(pChr.isNull())
		return ;
	
	std::list<ItemPtr> items;
	pChr->getItemsList(&items);
	
	std::map<uint32, ItemPtr> mapModelIds;
	
	std::list<ItemPtr>::iterator ii, endii = items.end();
	for(ii = items.begin(); ii != endii; ++ ii)
	{
		ItemPtr item = (*ii);
		if(item.isNull() || !item->isLoaded())
			continue;
		
		std::map<uint32, ItemPtr>::iterator fit = mapModelIds.find(item->model->getHandle());
		if(fit == mapModelIds.end())
		{
			mapModelIds.insert(std::make_pair(item->model->getHandle(), item));
		}
		else
		{
			uint32 orgNum = fit->second->getUInt32Field("num");
			fit->second->setUInt32Field("num", 0);
			fit->second->Destroy();
			
			uint32 num = item->getUInt32Field("num");
			item->setUInt32Field("num", num + orgNum);
			item->SaveDB();
			
			UpdateAboutMoney(pChr, uint32(item->model->getHandle()), num + orgNum);
		}
	}	
}

//-----------------------------------------------------------------------
void 	GameLogicManager::SelectLoginServer(UserAuthenticInfo * pInfo)
{
	WSSocketPtr socket = pInfo->pSocket;
	if(socket.isNull() || pInfo == NULL)
		return ;
	
	uint32 nowtime = time(0);
	char cCode[14] = "";
	if (pInfo->vecString.size() != 3 && pInfo->vecString.size() != 5)
	{
		Log.Debug(cCode,"SelectLoginServer Client[%d] %s Error User account  Size[%u]", \
				socket->getHandle(),socket->GetIP(), pInfo->vecString.size());
		socket->Disconnect();
		return;
	}
	
	String szUser = pInfo->vecString[0], szKey= pInfo->vecString[1],szMd5 = pInfo->vecString[2];
	Log.Debug("GameLogicManager::SelectLoginServer","szUser[%s]", szUser.c_str());
	WorldPacket packet;
	String szIP = "127.0.0.1";
	//获得用户表	
	ResourcePtr user_obj;
	std::list<ResourcePtr> users;
	sUserMgr.getDBObjects(&users, 0, 1, "name = '%s'", szUser.c_str());
	if (users.empty())
	{
		if (sXmlDataMgr.GetConfXMLValue("OPEN_DEBUG") && pInfo->platform_id)
		{
			CreateUser(szUser, pInfo->platform_id);
			sUserMgr.getDBObjects(&users, 0, 1, "name = '%s'", szUser.c_str());
			if (users.empty())
			{
				Log.Error("GameLogicManager Test", "SelectLoginServer user[%s] platform_id[%u] is empty!", szUser.c_str(), pInfo->platform_id);
				return;
			}
		}
		if (users.empty())
		{
			Log.Debug(cCode,"SelectLoginServer Client[%d] %s Error User account users Size[%u]", \
				socket->getHandle(),socket->GetIP(), users.size());
			socket->Disconnect();
			return;
		}
	}
	user_obj = users.front();
	if(user_obj.isNull())
	{
		Log.Debug(cCode,"SelectLoginServer Client[%d] %s Error User account  User:%s", \
		socket->getHandle(),socket->GetIP(),szUser.c_str());
		if (sProtocolsMgr.CreateUserLoginPacket(&packet, en_LS_InvalidUserOrSession))
			socket->SendPacket(&packet);
		socket->Disconnect();
		return;
	}
	
	user_obj->setHandle(user_obj->getUInt32Field("uid"));
	if(user_obj->getUInt32Field("ban_time") > nowtime)
	{
		Log.Debug(cCode,"Client[%d] %s locked User account  User:%s", \
		socket->getHandle(),socket->GetIP(),szUser.c_str());
		socket->Disconnect();
		return;
	}
	else
	{
		user_obj->setUInt32Field("ban_time", 0);
	}
	
	// 登录的时候，如果没有角色数据，就创建角色和银行。
	UserPtr pUser = user_obj;
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if (pChr.isNull())
	{
		pChr = sCharMgr.load(pUser->getUInt32Field("char_id"));
		if (pChr.isNull())
		{
			bool flag = true;
			std::list<GameBank> lstBankInfo;
			if (!sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", pUser->getUInt32Field("platform_id"), 1)){
				flag = false;
			}
			
			pChr = CreateCreature(pUser, flag);
			if(pChr.isNull())
			{
				Log.Debug(cCode,"Client[%d] %s Error user character:%d.", socket->getHandle(), socket->GetIP(), pUser->getUInt32Field("char_id"));
				socket->Disconnect();
				return ;
			}
			sBankMgr.AddBankInfo(pUser);
		}
	}
	
	// 验证密码
	CMD5 md5;
	String szPass = user_obj->getStringField("passwd");
	String transPass = md5.GenerateMD5(szPass.c_str());
	String fkgame = "FKGAME";
	uint32 uint_key = StringConverter::parseUnsignedInt(szKey);
	uint_key ^= 0xC3;
	String transKey = StringConverter::toString(uint_key);
	String token = transPass + szIP + szUser + transKey + fkgame;
	String md5Str = md5.GenerateMD5(token.c_str());	
	Log.Debug(cCode,"szKey[%s] token[%s]",szKey.c_str(),token.c_str());
	
	if(!sXmlDataMgr.GetConfXMLValue("OPEN_DEBUG") && md5Str != szMd5)
	{
		Log.Debug(cCode,"Client[%d] %s Error szPass:%s, token[%s]", socket->getHandle(),socket->GetIP(),szPass.c_str(), md5Str.c_str());
		if (sProtocolsMgr.CreateUserLoginPacket(&packet, en_LS_InvalidUserOrSession))
			socket->SendPacket(&packet);
		socket->Disconnect();
		return ;
	}
	// 取消二次登录，直接登录
	user_obj->setUInt32Field("active_gz_id", sChannelMgr.getServerID());
	user_obj->SaveDB();
	
	// 取得最佳服务器
	GameServer my_gs;
	GameServer lg_gs;
	if (sChannelMgr.getGameServer(sChannelMgr.getServerID(), my_gs))
	{
		Log.Notice("GameLogicManager::SelectLoginServer", "user[%u] select server my_gs.flag[%u]!", user_obj->getUInt32Field("uid"), my_gs.flag);
		if (my_gs.flag == GameServerFlagMaster)
		{// 是主登陆服务器			
			 uint32 id = user_obj->getUInt32Field("active_gz_id");
			if (id == 0)
			{
				if (!sChannelMgr.getBestLoginServer(lg_gs))
				{// 最佳游戏服
					socket->Disconnect();
					Log.Error("GameLogicManager Test", "user[%u] select server error!", user_obj->getUInt32Field("uid"));
					return;
				}
			}
			else
			{
				if (!sChannelMgr.getGameServer(id, lg_gs))
				{// 上次游戏服					
					sChannelMgr.getBestLoginServer(lg_gs);
				}
				else
				{
					if (lg_gs.status == GameServerStatusTimeout ||
					lg_gs.status == GameServerStatusError ||
					lg_gs.status == GameServerStatusNone)
					{
						sChannelMgr.getBestLoginServer(lg_gs);
					}
				}				
			}
			if (user_obj->isFreezeDB())
			{
				Log.Notice("GameLogicManager Test","user[%u] isFreezeDB!", user_obj->getUInt32Field("uid"));
			}
			
			user_obj->setUInt32Field("active_gz_id", lg_gs.server_id);
			user_obj->SaveDB();
			Log.Notice("GameLogicManager Test","SelectLoginServer user[%u] my_gs[%u] lg_gs[%u] active_gz_id[%u]", 
						user_obj->getHandle(), my_gs.server_id, lg_gs.server_id, user_obj->getUInt32Field("active_gz_id"));

			if ((lg_gs.flag & GameServerFlagMaster) && (my_gs.server_id == lg_gs.server_id))
			{// 如果最佳服务器是主服，则正常登陆				
				DisposeSceondLogin(pInfo);
			}
			else
			{ 
				// TODO:通知客户端二次连接			
				if (sProtocolsMgr.CreateLoginServerPacket(&packet, lg_gs, false))
					socket->SendPacket(&packet);				
			} 
			return;
		}		
	}
	
	Log.Notice("GameLogicManager SelectLoginServer", "user[%u] select default server !", user_obj->getUInt32Field("uid"));
	DisposeSceondLogin(pInfo);
}
//-----------------------------------------------------------------------
void 	GameLogicManager::DisposeSceondLogin(UserAuthenticInfo * pInfo)
{
	WSSocketPtr socket = pInfo->pSocket;
	if(socket.isNull() || pInfo == NULL)
		return ;
	
	uint32 nowtime = time(0);
	char cCode[256] = "GameLogicManager::DisposeSceondLogin";
	uint32 length = pInfo->vecString.size();
	if (length != 3 && length != 5)
	{
		Log.Debug(cCode,"111DisposeSceondLogin Client[%d] %s Error User account  Size[%u]", \
				socket->getHandle(),socket->GetIP(), pInfo->vecString.size());
		socket->Disconnect();
		return;
	}
	
	String szUser = pInfo->vecString[0], szKey= pInfo->vecString[1],szMd5 = pInfo->vecString[2];
	uint32 device = pInfo->vecString.size() > 3 ? StringConverter::parseUnsignedInt(pInfo->vecString[3]) : 0;	
	
	WorldPacket packet;
	String szIP = "127.0.0.1";
	//获得用户表
	UserPtr user = sUserMgr.load(ServerDatabase.EscapeString(szUser));	
	if(user.isNull())
	{
		if (sXmlDataMgr.GetConfXMLValue("OPEN_DEBUG") && pInfo->platform_id)
		{// 未找到用户数据，创建新数据
			user = CreateUser(szUser, pInfo->platform_id);
			if (user.isNull())
			{
				Log.Error(cCode, "DisposeSceondLogin create user[%s] failed!", szUser.c_str());
			}
		}
		
		if (user.isNull())
		{
			Log.Debug(cCode,"DisposeSceondLogin Client[%d] %s Error User account  User:%s", \
			socket->getHandle(),socket->GetIP(),szUser.c_str());
			if (sProtocolsMgr.CreateUserLoginPacket(&packet, en_LS_InvalidUserOrSession))
				socket->SendPacket(&packet);
			socket->Disconnect();
			return;
		}
	}
	user->ReloadDB();
	if(user->getUInt32Field("ban_time") > nowtime)
	{
		Log.Debug(cCode,"Client[%d] %s locked User account  User:%s", \
		socket->getHandle(),socket->GetIP(),szUser.c_str());
		socket->Disconnect();
		return;
	}
	else
	{
		user->setUInt32Field("ban_time", 0);
	}
	
	// 验证密码
	CMD5 md5;
	String szPass = user->getStringField("passwd");
	String transPass = md5.GenerateMD5(szPass.c_str());
	String fkgame = "FKGAME";
	uint32 uint_key = StringConverter::parseUnsignedInt(szKey);
	uint_key ^= 0xC3;
	String transKey = StringConverter::toString(uint_key);
	String token = transPass + szIP + szUser + transKey + fkgame;
	String md5Str = md5.GenerateMD5(token.c_str());	
	Log.Debug(cCode,"szKey[%s] token[%s]",szKey.c_str(),token.c_str());
	
	if(!sXmlDataMgr.GetConfXMLValue("OPEN_DEBUG") && md5Str != szMd5)
	{
		Log.Debug(cCode,"Client[%d] %s Error szPass:%s, token[%s]", socket->getHandle(),socket->GetIP(),szPass.c_str(), md5Str.c_str());
		if (sProtocolsMgr.CreateUserLoginPacket(&packet, en_LS_InvalidUserOrSession))
			socket->SendPacket(&packet);
		socket->Disconnect();
		return ;
	}	
	if (user->getUInt32Field("status") == UserStatus_Releasing)
	{// 其它服务器正在释放用户
		Log.Error(cCode,"111Client[%d] %s Error user[%u] is releasing! active_gz_id[%u] serverid[%u]!", \
			socket->getHandle(),socket->GetIP(),user->getHandle(),user->getUInt32Field("active_gz_id"), sChannelMgr.getServerID());
		socket->Disconnect();
		
		return;
	}
	
	uint32 serverid = sChannelMgr.getServerID();
	if (user->getUInt32Field("active_gz_id") != serverid)
	{		
		Log.Error(cCode,"aaaClient[%d] %s Error user[%u] active_gz_id[%u] serverid[%u] nLogic[%u]", \
				socket->getHandle(),socket->GetIP(),user->getHandle(),user->getUInt32Field("active_gz_id"), sChannelMgr.getServerID(), pInfo->nLogic);
		socket->Disconnect();
		return;
	}
	GameServer gs;
	sChannelMgr.getGameServer(serverid, gs);
	if (gs.status != GameServerStatusStop && m_isCloseServer.GetVal())
	{
		m_isCloseServer.SetVal(false);		
	}
	// 获取角色信息
	uint32 char_id = user->getUInt32Field("char_id");
	// 更新socket
	ResourceProxy old_socket = user->m_Socket;	
	CharPtr pChr = sCharMgr.getByHandle(user->getUInt32Field("char_id"));
	if (pChr.isNull())
	{
		pChr = sCharMgr.load(user->getUInt32Field("char_id"));
		if (pChr.isNull())
		{
			bool flag = true;
			std::list<GameBank> lstBankInfo;
			if (!sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", user->getUInt32Field("platform_id"), 1)){
				flag = false;
			}
			
			pChr = CreateCreature(user, flag);
			if(pChr.isNull())
			{
				Log.Debug(cCode,"Client[%d] %s Error user character:%d.", \
				socket->getHandle(),socket->GetIP(),char_id);
				if (sProtocolsMgr.CreateUserLoginPacket(&packet, en_LS_InvalidUserOrSession))
					socket->SendPacket(&packet);
				
				socket->Disconnect();
				return ;
			}
			sBankMgr.AddBankInfo(user);
		}
	}

	int count = 0;
	while(!pChr->isLoaded() && ++count < 40)
	{
		Sleep(50);
	}
	
	if(!pChr->isLoaded())
	{
		Log.Debug(cCode,"Client[%d] %s Error character:%d. load 2's failed.", \
		socket->getHandle(),socket->GetIP(),char_id);
		
		if (sProtocolsMgr.CreateUserLoginPacket(&packet, en_LS_InvalidUserOrSession))
			socket->SendPacket(&packet);
		
		socket->Disconnect();
		return ;
	}
	if (pChr->isFreezeDB())
	{// 如果是冻结，则解除，并重新加载
		ResourceEvent event;
		event.event_id = ResourceEvent_Unfreeze;
		pChr->SendEvent(&event);
		pChr->reload();
	}
	if(!old_socket.isNull())
	{
		if(old_socket._handle != socket->getHandle())
		{
			WSSocketPtr old_sock = old_socket.getResourcePtr();
			if(!old_sock.isNull())
			{// 退出的日志
				// 设置强制关闭连接
				old_sock->setForceClose(true);
				Log.Debug(cCode,"Client[%d] %s Error old_sock not null character:%d.", \
								socket->getHandle(),socket->GetIP(),char_id);
				old_sock->Disconnect();
			}
		}
	}
	socket->setCurrentUser(user);
	socket->setCurrentCharacter(pChr);
	
	user->m_Socket = (ResourceProxy)socket;	
	bool isMainGame = !(user->getUInt32Field("gz_id") == sBankMgr.GetGameGZID(user));	
	user->setUInt32Field("flag", isMainGame);
	// 在线情况 手机/WEB
	user->setUInt32Field("status", device?device:UserStatus_Online);
	if(device)
	{// 手机设备登陆
		socket->setCheckTimetOut(true);
		uint32 timeout = sXmlDataMgr.GetConfXMLValue("SOCKET_TIME_OUT");
		if (timeout == 0)
			timeout = 300000;
		socket->setTimeOutTimer(timeout);
	}
	user->setStringField("ip", socket->GetIP());
	String strAddress = sShowIP.searchXMLAddress(user->getUInt32Field("platform_id"));
	String strRealAddress = sShowIP.getAddress(socket->GetIP());
	if(!strRealAddress.compare("台灣省") || !strRealAddress.compare("臺灣省") || !strRealAddress.compare("台湾省"))
		strRealAddress = "台灣";
	
	user->setStringField("addr", strAddress == "" ? strRealAddress : strAddress);	
	Log.Debug(cCode,"user pid[%u] ip[%s] addr[%s] showip getaddr[%s]", 
						user->getUInt32Field("platform_id"), socket->GetIP(), user->getStringField("addr").c_str(), sShowIP.getAddress(socket->GetIP()).c_str());
	// 处理上次登陆游戏服务器数据
	uint32 gameid = user->getUInt32Field("gz_id");
	if(pChr->getUInt32Field("ishere") == 0)
		pChr->setUInt32Field("ishere", gameid);	
	pChr->setUInt32Field("gz_id", gameid);	
	
	// 记录登录成功日志
	sLogDataMgr.LoginLog(user, GameServerTypeWorld);
	// 发送消息，登录成功
	if (sProtocolsMgr.CreateUserLoginPacket(&packet, en_LS_Ok))
		socket->SendPacket(&packet);
	Log.Debug(cCode,"DisposeSceondLogin szKey[%s] token[%s] pInfo->isCenter[%u] ok!",
						szKey.c_str(),md5Str.c_str(), pInfo->isCenter);
	
	user->SaveDB();
}
//-----------------------------------------------------------------------
void 	GameLogicManager::WorldUserAuthentication(UserAuthenticInfo * pInfo)
{
	WSSocketPtr socket = pInfo->pSocket;
	if(socket.isNull() || pInfo == NULL)
		return ;
	
	uint32 nowtime = time(0);
	char cCode[14] = "";
	if (pInfo->vecString.size() != 3 && pInfo->vecString.size() != 5)
	{
		Log.Debug(cCode,"WorldUserAuthentication Client[%d] %s Error User account  Size[%u]", \
				socket->getHandle(),socket->GetIP(), pInfo->vecString.size());
		socket->Disconnect();
		return;
	}
	
	String szUser = pInfo->vecString[0], szKey= pInfo->vecString[1],szMd5 = pInfo->vecString[2];
	uint32 device = pInfo->vecString.size() > 3 ? StringConverter::parseUnsignedInt(pInfo->vecString[3]) : 0;	
	WorldPacket packet;
	String szIP = "127.0.0.1";
	//获得用户表
	UserPtr user = sUserMgr.load(ServerDatabase.EscapeString(szUser));	
	if(user.isNull())
	{
		if (sXmlDataMgr.GetConfXMLValue("OPEN_DEBUG") && pInfo->platform_id)
		{// 未找到用户数据，创建新数据
			user = CreateUser(szUser, pInfo->platform_id);
			if (user.isNull())
			{
				Log.Error("GameLogicManager Test", "WorldUserAuthentication create user[%s] failed!", szUser.c_str());
			}
		}
		
		if (user.isNull())
		{
			Log.Debug(cCode,"WorldUserAuthentication Client[%d] %s Error User account  User:%s", \
			socket->getHandle(),socket->GetIP(),szUser.c_str());
			if (sProtocolsMgr.CreateUserLoginPacket(&packet, en_LS_InvalidUserOrSession))
				socket->SendPacket(&packet);
			socket->Disconnect();
			return;
		}
	}
	
	if(user->getUInt32Field("ban_time") > nowtime)
	{
		Log.Debug(cCode,"Client[%d] %s locked User account  User:%s", \
		socket->getHandle(),socket->GetIP(),szUser.c_str());
		socket->Disconnect();
		return;
	}
	else
	{
		user->setUInt32Field("ban_time", 0);
	}
	
	if (user->getUInt32Field("active_gz_id") == 0)
		user->setUInt32Field("active_gz_id", sChannelMgr.getServerID());	
	// 验证密码
	CMD5 md5;
	String szPass = user->getStringField("passwd");
	String transPass = md5.GenerateMD5(szPass.c_str());
	String fkgame = "FKGAME";
	uint32 uint_key = StringConverter::parseUnsignedInt(szKey);
	uint_key ^= 0xC3;
	String transKey = StringConverter::toString(uint_key);
	String token = transPass + szIP + szUser + transKey + fkgame;
	String md5Str = md5.GenerateMD5(token.c_str());	
	Log.Debug(cCode,"szKey[%s] token[%s]",szKey.c_str(),token.c_str());
	
	if(!sXmlDataMgr.GetConfXMLValue("OPEN_DEBUG") && md5Str != szMd5)
	{
		Log.Debug(cCode,"Client[%d] %s Error szPass:%s, token[%s]", socket->getHandle(),socket->GetIP(),szPass.c_str(), md5Str.c_str());
		if (sProtocolsMgr.CreateUserLoginPacket(&packet, en_LS_InvalidUserOrSession))
			socket->SendPacket(&packet);
		socket->Disconnect();
		return ;
	}	
	
	// 获取角色信息
	uint32 char_id = user->getUInt32Field("char_id");
	// 更新socket
	ResourceProxy old_socket = user->m_Socket;		
	CharPtr pChr = sCharMgr.getByHandle(user->getUInt32Field("char_id"));
	if (pChr.isNull())
	{
		pChr = sCharMgr.load(user->getUInt32Field("char_id"));
		if (pChr.isNull())
		{
			bool flag = true;
			std::list<GameBank> lstBankInfo;
			if (!sChannelMgr.getBankList(&lstBankInfo, 0, 1, "`platform_id` = %u and `type` = %u", user->getUInt32Field("platform_id"), 1)){
				flag = false;
			}
			
			pChr = CreateCreature(user, flag);
			if(pChr.isNull())
			{
				Log.Debug(cCode,"Client[%d] %s Error user character:%d.", \
				socket->getHandle(),socket->GetIP(),char_id);
				if (sProtocolsMgr.CreateUserLoginPacket(&packet, en_LS_InvalidUserOrSession))
					socket->SendPacket(&packet);
				
				socket->Disconnect();
				return ;
			}
			sBankMgr.AddBankInfo(user);
		}
	}

	int count = 0;
	while(!pChr->isLoaded() && ++count < 40)
	{
		Sleep(50);
	}
	if(!pChr->isLoaded())
	{
		Log.Debug(cCode,"Client[%d] %s Error character:%d. load 2's failed.", \
		socket->getHandle(),socket->GetIP(),char_id);
		
		if (sProtocolsMgr.CreateUserLoginPacket(&packet, en_LS_InvalidUserOrSession))
			socket->SendPacket(&packet);
		
		socket->Disconnect();
		return ;
	}
	if (pChr->isFreezeDB())
	{// 如果是冻结，则解除，并重新加载
		ResourceEvent event;
		event.event_id = ResourceEvent_Unfreeze;
		pChr->SendEvent(&event);
		pChr->reload();
	}
	if(!old_socket.isNull())
	{
		if(old_socket._handle != socket->getHandle())
		{
			WSSocketPtr old_sock = old_socket.getResourcePtr();
			if(!old_sock.isNull())
			{// 退出的日志
				Log.Debug(cCode,"Client[%d] %s Error old_sock not null character:%d.", \
								socket->getHandle(),socket->GetIP(),char_id);
				old_sock->Disconnect();
			}
		}
	}
	socket->setCurrentUser(user);
	socket->setCurrentCharacter(pChr);
	
	user->m_Socket = (ResourceProxy)socket;	
	bool isMainGame = !(user->getUInt32Field("gz_id") == sBankMgr.GetGameGZID(user));	
	user->setUInt32Field("flag", isMainGame);
	if (device)
	{
		user->setUInt32Field("status", device);
		// 不检查ping
		socket->setCheckTimetOut(true);
		uint32 timeout = sXmlDataMgr.GetConfXMLValue("SOCKET_TIME_OUT");
		if (timeout == 0)
			timeout = 300000;
		socket->setTimeOutTimer(timeout);
	}
	else
	{
		// pc在线
		user->setUInt32Field("status", UserStatus_Online);
	}
	
	// 在线情况 手机/WEB
	user->setStringField("ip", socket->GetIP());
	String strAddress = sShowIP.searchXMLAddress(user->getUInt32Field("platform_id"));
	user->setStringField("addr", strAddress == "" ? sShowIP.getAddress(socket->GetIP()) : strAddress);	
	// 处理上次登陆游戏服务器数据
	uint32 gameid = user->getUInt32Field("gz_id");
	if(pChr->getUInt32Field("ishere") == 0)
		pChr->setUInt32Field("ishere", gameid);	
	pChr->setUInt32Field("gz_id", gameid);	
	
	uint32 icon_id = pChr->getUInt32Field("id");
	if(icon_id < 500)
		pChr->setUInt32Field("id",411);
	else
		pChr->setUInt32Field("id",511);
	
	// 记录登录成功日志
	sLogDataMgr.LoginLog(user, GameServerTypeWorld);
	
	// 发送消息，登录成功
	if (sProtocolsMgr.CreateUserLoginPacket(&packet, en_LS_Ok))
		socket->SendPacket(&packet);
	Log.Debug(cCode,"WorldUserAuthentication szKey[%s] token[%s] pInfo->isCenter[%u] ok! config[%s]",
		szKey.c_str(),md5Str.c_str(), pInfo->isCenter, user->getStringField("config").c_str());
	user->SaveDB();
}

//-----------------------------------------------------------------------
bool 	GameLogicManager::DisposeAuthentication(CharPtr & pChr)
{	
	if (pChr.isNull())
		return false;
	
	WSSocketPtr socket = pChr->getSocket();
	if (socket.isNull())
		return false;	
	
	UserPtr user = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (user.isNull())
		return false;
	
	WorldPacket packet;
	uint32 nowtime = time(0);
	uint16 currGZID = 0;
	sBankMgr.JoinGameServer(user, user->getUInt32Field("gz_id"), &currGZID);
	// 银行公共数据
	BankPublicData bank_data;
	sBankMgr.GetPublicData(user, &bank_data);
	
	// 设置玩家当前位置
	pChr->setUInt32Field("ishere", currGZID ? currGZID : user->getUInt32Field("gz_id"));
	// 是否开户首充通道
	// uint32 offsetDate = sTools.GetOffsetDate(bank_data.FirstBuyTimer, nowtime);
	if (!(bank_data.FirstBuyTimer))
	{// 开启首充通道
		if (sProtocolsMgr.CreateTellToDoPacket(&packet, en_RemindType_OpenFirstBuy))
			socket->SendPacket(&packet);
	}
	// 通知周卡月卡信息
	std::list<VIPCard> lstWelfare;
	sVipCardMgr.GetSelfWelfareList(pChr, lstWelfare);
	
	GameBank bank;
	sBankMgr.GetPublicData(user, &bank);
	
	// 更新银行代理商ID
	Fields fields;
	fields["agentid"] = uint32(user->getUInt32Field("reg_from"));
	sBankMgr.UpdateCenterBank(&fields, "platform_id = %u and agentid = 0 and type = 1", user->getUInt32Field("platform_id"));
	
	bool bHaveWeekCard = false;
	bool bHaveMonthCard = false;
	std::list<VIPCard>::iterator itVip, eiVip = lstWelfare.end();
	for(itVip = lstWelfare.begin(); itVip!=eiVip; ++itVip)
	{
		uint32 endTime = 0;
		uint32 *pEndTime = pChr->user_data.Get<uint32>((*itVip).key);
		if (pEndTime == NULL)
			continue;
		
		endTime = *pEndTime;
		uint8 status = 2;
		uint8 type = 0;
		if(!(*itVip).key.compare("VIP_WEEKCARD"))
		{
			type = en_RemindType_WeekCard;
			bHaveWeekCard = true;
			uint32 last_welfaretime = sBankMgr.GetUserDataVal(bank, "FLZHOULB");
			if (!sTools.IsSameDay(last_welfaretime, nowtime))
				status = 1;
		}
		else if(!(*itVip).key.compare("VIP_WEEKCARD"))
		{
			type = en_RemindType_MonthCard;
			bHaveMonthCard = true;
			uint32 last_welfaretime = sBankMgr.GetUserDataVal(bank, "FLYUELB");
			if (!sTools.IsSameDay(last_welfaretime, nowtime))
				status = 1;
		}
		else
			continue;
		
		// 操作类型 时间 状态（0 可购买 1 可领 2 已领）
		if (sProtocolsMgr.CreateTellToDoPacket(&packet, type, endTime, status))
			socket->SendPacket(&packet);
	}
	
	if(!bHaveWeekCard)
	{// 周卡可买
		if (sProtocolsMgr.CreateTellToDoPacket(&packet, en_RemindType_WeekCard, 0, 0))
			socket->SendPacket(&packet);
	}
	
	if(!bHaveMonthCard)
	{// 月卡可买
		if (sProtocolsMgr.CreateTellToDoPacket(&packet, en_RemindType_MonthCard, 0, 0))
			socket->SendPacket(&packet);
	}
	
	// 注册时间
	if(sProtocolsMgr.CreateUserPublicDataPacket(&packet,user->getUInt32Field("reg_time")))
		socket->SendPacket(&packet);
	
	// 更新VIP数据
	sVipCardMgr.UpdateVIPDate(pChr);
	// 登录成功后后续处理
	sHallMgr.AfterLoginWorldOk(socket, user, pChr);
	// 已购买形象列表
	if (sProtocolsMgr.CreateBodyListPacket(&packet, pChr))
		socket->SendPacket(&packet);		
	// 下发系统设置
	if(sProtocolsMgr.CreateSystemSetPacket(&packet,user))	
		socket->SendPacket(&packet);
	
	sBankMgr.UserLogin(user);
	
	bool bSendOpenBag = false;
	bool bUpdateCoins = false;
	// 告诉玩家目前的游戏
	uint16 ishere = pChr->getUInt32Field("ishere");
	Log.Debug("GameLogicManager::DisposeAuthentication","char[%u] pid[%u] ishere[%u] gz_id[%u]", pChr->getHandle(), user->getUInt32Field("platform_id"), ishere, user->getUInt32Field("gz_id"));
	if(ishere != user->getUInt32Field("gz_id"))
	{// 发送网关让玩家退出服务器
		
		Json::Value val;
		val["gz_id"] = uint32(ishere);
		val["platform_id"] = uint32(user->getUInt32Field("platform_id"));
		val["agent_id"] = uint32(user->getUInt32Field("reg_from"));
		
		Json::FastWriter w;
		if(SendExitGameServerGateway(w.write(val)))
		{
			pChr->setUInt32Field("ishere", user->getUInt32Field("gz_id"));
			ishere = user->getUInt32Field("gz_id");
			
			uint16 currGZID = 0;
			sBankMgr.JoinGameServer(user, ishere, &currGZID);
			
			if (sProtocolsMgr.CreateOpenBackpackPacket(&packet, pChr))
				socket->SendPacket(&packet);
			if (sProtocolsMgr.CreateExchangeBagPacket(&packet, pChr))
				socket->SendPacket(&packet);
			bSendOpenBag = true;
			bUpdateCoins = true;
		}
	}
	else
	{// 同步外部平台积分积分
		bUpdateCoins = true;
		
		// 更新玩家俱乐部经费
		sCenterClubMgr.UpdateClubActivityValueByCraeter(pChr);
	}
	
	if(bUpdateCoins && user->getUInt32Field("reg_from") == 5050)
	{// 休闲积分同步
		uint32 platform_coins = GetAgentCoinsNum(pChr);
		uint32 curr_coins = GetItemNum(pChr, ItemModel_Coins);
		
		if(platform_coins != curr_coins)
		{
			SetItemNum(pChr, ItemModel_Coins, platform_coins);
			Log.Warning("GameLogicManager::DisposeAuthentication","char[%u] update org coins[%u] platform coins[%u]", pChr->getHandle(), curr_coins, platform_coins);
		}
	}
	
	if(!bSendOpenBag)
	{
		// 发送背包数据
		if (sProtocolsMgr.CreateOpenBackpackPacket(&packet, pChr))
			socket->SendPacket(&packet);
		if (sProtocolsMgr.CreateExchangeBagPacket(&packet, pChr))
			socket->SendPacket(&packet);
	}
	
	if(sBankMgr.CreateOpServerResult(&packet, 0, 0, ishere))
		socket->SendPacket(&packet);
	
	if(!IsSameDate(user->getUInt32Field("ll_time"),nowtime))
	{// 新的一天重置数据
		resetSomeData(pChr);
	}
	
	user->setUInt32Field("ll_time", nowtime);
	// 登录事件
	ResourceEvent event;
	event.event_id = ResourceEvent_Login;
	pChr->SendEvent(&event);
	pChr->SaveDB();
	user->SaveDB();
	
	// 检测过期邮件
	CheckExpireMails(user->getUInt32Field("platform_id"), user->getUInt32Field("gz_id"));
	
	// 发送一些客户端 需要的牌桌信息
	AICreatureBaseInterface * pChrInter = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(!pChrInter)
		return false;
	
	ChannelPtr pChannel = pChrInter->GetChannelPtr(); 
	if(!pChannel.isNull())
	{
		AIChannelBaseInterface *pAiChanInfe = TO_CHANNEL_BASE_INTERFACE(pChannel->getAIInterface());
		if (pAiChanInfe)
			pAiChanInfe->SendSomeChannelInfo();
	}
	
	sCenterFriendsMgr.UpdateFriendGameStatus(pChr, enFriendGameStatus_Free, false);
	Log.Notice("GameLogicManager Test","DisposeAuthentication pChr[%u][%s] login ok!", pChr->getHandle(), pChr->getStringField("name").c_str());
	return true;
}

bool GameLogicManager::DisposeRobotAuthentication(CharPtr & pChr)
{
	if (pChr.isNull())
		return false;
	
	UserPtr user = sUserMgr.load(pChr->getUInt32Field("userid"));
	if (user.isNull())
		return false;
	
	uint16 currGZID = 0;
	sBankMgr.JoinGameServer(user, user->getUInt32Field("gz_id"), &currGZID);	
	// 设置玩家当前位置
	pChr->setUInt32Field("ishere", currGZID ? currGZID : user->getUInt32Field("gz_id"));
	
	sBankMgr.UserLogin(user);
	
	bool bLoginSucess = true;
	// 告诉玩家目前的游戏
	uint8 ishere = pChr->getUInt32Field("ishere");
	if(ishere != user->getUInt32Field("gz_id"))
	{// 发送网关让玩家退出服务器

		Json::Value val;
		val["gz_id"] = uint32(ishere);
		val["platform_id"] = uint32(user->getUInt32Field("platform_id"));
		val["agent_id"] = uint32(user->getUInt32Field("reg_from"));
		
		Json::FastWriter w;
		String strData;
		if(SendExitGameServerGateway(w.write(val)))
		{
			pChr->setUInt32Field("ishere", user->getUInt32Field("gz_id"));
			ishere = user->getUInt32Field("gz_id");
			
			uint16 currGZID = 0;
			sBankMgr.JoinGameServer(user, ishere, &currGZID);
		}
		else
		{
			bLoginSucess = false;
		}
	}
	
	pChr->SaveDB();
	user->SaveDB();
	return bLoginSucess;
}

//-----------------------------------------------------------------------
bool 	GameLogicManager::WebUserLogingBounty(CharPtr & pChr)
{
	if(pChr.isNull())
		return false;	
	
	uint32 weblv = pChr->getUInt32Field("rank");
	if(!weblv)
		return false;
	
	WSSocketPtr pSocket = pChr->getSocket();
	if(pSocket.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint32 ll_time = pUser->getUInt32Field("ll_time");
	uint32 old_date = GetCurDate(ll_time);
	uint32 now_date = GetCurDate(now());
	if(old_date != now_date)
	{
		const WebLvBounty* pBounty = sXmlDataMgr.GetWebLevelBounty(weblv);
		if(pBounty)
		{
			if(pBounty->money)
				addItemNum(pChr, ItemModel_Coins, pBounty->money, false);
			if(pBounty->match)
				addItemNum(pChr, ItemModel_March, pBounty->match, false);
			if(pBounty->change)
				addItemNum(pChr, ItemModel_Lottery, pBounty->change, false);
		}
	}
	
	return true;
}

//-----------------------------------------------------------------------
// 这个函数还需要再追加几个参数，用于存入日志data7和data8
bool GameLogicManager::CreateMail(const uint32 & pid, const String & szTitle, 
									const String & szContent,
									const uint32 & send_uid,
									const uint32 & reson,
									std::map<uint32,uint32> * mapItems)
{
	if(pid == 0)
		return false;
	GameMail *pMail = sChannelMgr.newDumyMail();
	if(pMail == NULL)
		return false;
	pMail->group_id = sChannelMgr.getGroupID(); // 邮件组ID
	pMail->status = Mail::MailStatusRecv; // 邮件状态
	pMail->recv_serial = pid; // 接收方用户ID
	pMail->title = szTitle; // 标题
	
	uint32 hasitem = 0;	// 是否有附件
	Json::Value val;
	
	uint32 gz_id = 0;
	
	if(mapItems && mapItems->size())
	{
		char str[16];
		std::map<uint32,uint32>::iterator iter,ei = mapItems->end();
		for (iter=mapItems->begin(); iter!=ei; iter++)
		{
			if (iter->first==0 || iter->second==0)
				continue;
			sprintf(str, "%d", iter->first);
			hasitem = 1;
			val["items"][str] = iter->second;
		}
	}
	if(send_uid)
	{
		UserPtr pUser = sUserMgr.getByHandle(send_uid);
		if(!pUser.isNull())
		{
			gz_id = pUser->getUInt32Field("gz_id");
			val["send_serial"] = pUser->getUInt32Field("platform_id");			// 发件方ID（0 表示系统）
			val["send_user"] = pUser->getStringField("nick");
		}
	}
	val["content"] = szContent;
	
	Json::FastWriter w;
	pMail->contenct = w.write(val); // 内容
	
	pMail->data1 = hasitem;			// 是佛有添加附件（0 否 1 有）
	pMail->data2 = reson;			// 添加原因（可用来当做日志类型用）
	
	pMail->create_time = time(0); 		// 创建时间
	
	uint32 expiration_days = sXmlDataMgr.GetConfXMLValue("MAIL_LIMITDAYS");
	if(expiration_days == 0 )	//默认一周
		expiration_days = 7;
	
	pMail->expiration_time = time(0) + expiration_days * 86400; 	// 过期时间
	
	sChannelMgr.addMailDB(pMail);
	sChannelMgr.freeDumyMail(pMail);
	//检测过期邮件
	CheckExpireMails(pid,gz_id);
	return true;
}

// 添加带铜钱的附件
bool GameLogicManager::CreateCoinsMail(const uint32 & pid,const String & szTitle,const String & szContent,const uint32 & coins)
{
	std::map<uint32,uint32> mapItems;
	mapItems.insert(std::make_pair(ItemModel_Coins,coins));
	
	return CreateMail(pid,szTitle,szContent,0,0,&mapItems);
}

//-----------------------------------------------------------------------
bool GameLogicManager::CreateBonusMail(UserPtr & pUser, const uint32 & town_id, const uint32 & model_id, const uint32 & num, const uint32 & order)
{
	if(pUser.isNull())
		return false;
	
	uint32 gameid = pUser->getUInt32Field("gz_id");
	String szGameName = sXmlDataMgr.GetGzIdName(gameid);
	const MailModel *pModel = sXmlDataMgr.GetMailModel("MARCH_BONUS");
	if(pModel == NULL)
		return false;
	
	ItemModelPtr pItemModel = sItemModelMgr.getByHandle(model_id);
	if(pItemModel.isNull())
		return false;
	
	TownPtr pTown = sTownMgr.getByHandle(town_id);
	if(pTown.isNull())
		return false;
		
	char strContent[512] = "";
	sprintf(strContent, pModel->szContent.c_str(), 
		pUser->getStringField("nick").c_str(), szGameName.c_str(), 
		pTown->getStringField("name").c_str(), order, num, pItemModel->getStringField("name").c_str());	
	
	CreateMail(pUser->getUInt32Field("platform_id"), pModel->szTitle, strContent);
	
	if(pUser->m_Socket.isNull())
		return true;
		
	WSSocketPtr pSocket = pUser->m_Socket.getResourcePtr();
	if(pSocket.isNull())
		return true;
		
	WorldPacket packet;
	if (sProtocolsMgr.CreateSendUnreadMailNumberPacket(&packet, pUser))
		pSocket->SendPacket(&packet);

	return true;
}

bool GameLogicManager::CreateChangeMail(UserPtr & pUser, const String & szItemName, const String & szOrderfrom)
{
	if(pUser.isNull())
		return false;
		
	const MailModel *pModel = sXmlDataMgr.GetMailModel("SHIWUDUIHUAN");
	if(pModel == NULL)
		return false;
	char strContent[512] = "";
	sprintf(strContent, pModel->szContent.c_str(), pUser->getStringField("nick").c_str(), szItemName.c_str(), szOrderfrom.c_str());
	CreateMail(pUser->getUInt32Field("platform_id"), pModel->szTitle, strContent);
	if(pUser->m_Socket.isNull())
		return true;
		
	WSSocketPtr pSocket = pUser->m_Socket.getResourcePtr();
	if(pSocket.isNull())
		return true;
		
	WorldPacket packet;
	if (sProtocolsMgr.CreateSendUnreadMailNumberPacket(&packet, pUser))
		pSocket->SendPacket(&packet);

	return true;
}

bool GameLogicManager::CreatePracticMail(UserPtr & pUser, const uint32 & town_id, const String & szCode)
{
	if(pUser.isNull())
		return false;
	
	const MailModel *pModel = sXmlDataMgr.GetMailModel("PRACTIC_MAIL");
	if(pModel == NULL)
		return false;
	
	uint32 gameid = pUser->getUInt32Field("gz_id");
	String szGameName = sXmlDataMgr.GetGzIdName(gameid);
	
	TownPtr pTown = sTownMgr.getByHandle(town_id);
	if(pTown.isNull())
		return false;
	
	char strContent[1024] = "";
	sprintf(strContent, pModel->szContent.c_str(), pUser->getStringField("nick").c_str(), 
		szGameName.c_str(), pTown->getStringField("name").c_str(), pTown->getStringField("desc").c_str(), szCode.c_str());
	
	CreateMail(pUser->getUInt32Field("platform_id"), pModel->szTitle, strContent);
	if(pUser->m_Socket.isNull())
		return true;
		
	WSSocketPtr pSocket = pUser->m_Socket.getResourcePtr();
	if(pSocket.isNull())
		return true;
		
	WorldPacket packet;
	if (sProtocolsMgr.CreateSendUnreadMailNumberPacket(&packet, pUser))
		pSocket->SendPacket(&packet);
	
	return true;
}

//-----------------------------------------------------------------------
bool GameLogicManager::IsSameDate(time_t t1, time_t t2)
{
	if (0 == t1)
		return false;
	if (0 == t2)
		t2 = time(0);
	tm t1Tm = *(localtime(&t1));
	tm *pt2Tm = localtime(&t2);
	return (pt2Tm->tm_yday == t1Tm.tm_yday && pt2Tm->tm_year == t1Tm.tm_year);
}

//-----------------------------------------------------------------------
bool GameLogicManager::AddCreatureExps(CharPtr & pChr, const uint32 & addnum)
{
	if(pChr.isNull() || !addnum)
		return false;
		
	bool bUP = false;		
	uint32 addexp = addnum;
	uint32 currExp = pChr->getUInt32Field("exps");
	pChr->setUInt32Field("exps", currExp + addexp);
	//等级是否到达上限
	uint32 max_lv = sXmlDataMgr.GetMaxLevel();
	uint32 lv = pChr->getUInt32Field("lv");
	if(lv >= max_lv)
	{
		return EVERET_NONE;		
	}
	
	uint32 nextEXP = sXmlDataMgr.GetExpsOfLevel(lv+1);
	uint32 exp = pChr->getUInt32Field("exps");
	
	// 记录经验等级日志
	while(exp >= nextEXP)
	{
		bUP = true;
		exp -= nextEXP;
		
		if(++lv > max_lv)
			break;
		
		nextEXP = sXmlDataMgr.GetExpsOfLevel(lv+1);
		
		pChr->setUInt32Field("lv", lv);
		pChr->setUInt32Field("exps", exp);
	}
	
	if(bUP)
	{// 升级了
		MammonCome(pChr, true);
	}

	return bUP;
}

//-------------------------------------------
uint8 GameLogicManager::ProvideLoginGift(CharPtr &pChr, bool isInstant)
{
	if(pChr.isNull())
		return 0;
		
	WSSocketPtr pSocket = pChr->getSocket();
	if(pSocket.isNull())
		return 0;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return 0;
	
	const std::map<uint32, LoginGift> &mapLoginGift = sXmlDataMgr.GetLoginGiftMap();
	if (mapLoginGift.empty())
		return 0;
	// 计算发哪种奖励
	time_t lastTime = pUser->getUInt32Field("fame");
	time_t curTime = time(0);
	uint32 days = 1;
	std::map<uint32, LoginGift>::const_reverse_iterator iter = mapLoginGift.rbegin(), iterEnd = mapLoginGift.rend();
	if (lastTime > 0)
	{
		if (curTime < lastTime)
			return 0;
		tm lastTm = *(localtime(&lastTime));
		tm *pCurTm = localtime(&curTime);
		uint32 offsetDays;	
		if (pCurTm->tm_year == lastTm.tm_year)
			offsetDays = pCurTm->tm_yday - lastTm.tm_yday;
		else
			offsetDays = (pCurTm->tm_yday + dysize(lastTm.tm_year + 1900)) - lastTm.tm_yday;
		if (offsetDays == 0)
			return 0;
		--offsetDays;
		days = pUser->getUInt32Field("honor");
		uint32 maxDays = iter->first;
		if (0 == offsetDays)
			days < maxDays ? ++days : (days = maxDays);
		else
			days < offsetDays ? (days = 1) : (days -= offsetDays);
	}
	
	if(isInstant)
	{
		uint32 modelId = 0;
		uint32 number = 0;
		
		for (; iter != iterEnd; ++iter)
		{
			if (days >= iter->first)
			{
				modelId = iter->second.modelId;
				number = iter->second.number;
				pChr->setUInt32Field("marriage", 0);
				AICreatureBaseInterface * pACBI = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
				if(pACBI == NULL)
					return 0;
					
				if(pChr->getUInt32Field("rank"))
				{// 是黄钻用户				
					// 重置黄钻登陆奖励,未领取
					pACBI->SetXMLData("HZDLLB", 0);
				}
				
				break;
			}	
		}
		
		// 会员额外奖励
		sVipCardMgr.AddLoginGift(pChr, number);
		// 发奖
		sGLMgr.addItemNum(pChr, modelId, number);
		
		// 发送消息
		sGLMgr.SendAddItemMessage(pChr, modelId, number, "login_bourty");
		// 记录日志
		sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Hortation, modelId, en_UNT_Add, number, en_HSI_Login);
		// 存入数据库
		pUser->setUInt32Field("honor",days); // 连续天数
		pUser->setUInt32Field("fame",curTime); // 领奖时间
	}
	
	return days;
}
//-----------------------------------------------------------------------
ItemPtr GameLogicManager::AddMammonCard(CharPtr & chr, const uint32 modelId, const uint32 addnum)
{
	ItemPtr item = GetItem(chr, modelId);
	if(item.isNull())
		return CreateItem(chr, modelId, addnum);
	uint32 num = item->getUInt32Field("num");
	num += addnum;
	item->setUInt32Field("num", num);
	item->SaveDB();
	// 下发更新物品数量
	WorldPacket newP;
	if(sProtocolsMgr.CreateUpdateItemNumberPacket(&newP, modelId, num))
		SendProtocolsToChr(chr, &newP);
	return item;
}
//-----------------------------------------------------------------------
bool GameLogicManager::ReduceMammonCard(CharPtr & chr, const uint32 rNum, uint32 &coins)
{
	if (chr.isNull())
		return false;
	list<ItemPtr> lstItems;
	chr->getItemsList(&lstItems);
	ItemPtr item;
	uint32 multiple = 0;
	// 获取背包物品信息
	list<ItemPtr>::iterator iter = lstItems.begin(), iterEnd = lstItems.end();
	for(; iter !=iterEnd; ++iter)
	{
		if((*iter)->getItemStatus() == Item::ItemStatusDeleted)
			continue;
		ItemModelPtr & model = (*iter)->model;
		if(model.isNull())
			continue;
		if (model->getUInt32Field("type") == 1 && model->getUInt32Field("sub_type") == 1)
		{
			if ((*iter)->getUInt32Field("num") > 0 && model->getUInt32Field("maxhp") > multiple)
			{
				multiple = model->getUInt32Field("maxhp"); // 倍数
				item.setNull();
				item = *iter;
			}
		}
	}
	if(item.isNull())
		return false;
	uint32 cur_num = item->getUInt32Field("num");
	if(cur_num < rNum)
		return false;
	coins = uint32(coins * (1 + multiple * 0.01f));
	cur_num -= rNum;
	item->setUInt32Field("num", cur_num);
	item->SaveDB();
	// 下发更新物品数量
	WorldPacket newP;
	if(sProtocolsMgr.CreateUpdateItemNumberPacket(&newP, item->model->getHandle(), cur_num))
		SendProtocolsToChr(chr, &newP);
	sLogDataMgr.UpdateItemsInfoLog(chr, en_ST_Gateway, item->model->getHandle(), en_UNT_Reduce, rNum);
	return true;
}
//-----------------------------------------------------------------------
bool GameLogicManager::UpdateMammonCard(CharPtr & chr)
{
	if (chr.isNull())
		return false;
	list<ItemPtr> lstItems;
	chr->getItemsList(&lstItems);
	// 获取背包物品信息
	list<ItemPtr>::iterator iter = lstItems.begin(), iterEnd = lstItems.end();
	for(; iter !=iterEnd; ++iter)
	{
		ItemPtr item = *iter;
		if(item->getItemStatus() == Item::ItemStatusDeleted)
			continue;
		ItemModelPtr & model = item->model;
		if(model.isNull())
			continue;
		if (model->getUInt32Field("type") == 1 && model->getUInt32Field("sub_type") == 1) // 找到财神卡
		{
			if (sTools.IsSameYear(item->getUInt32Field("handle_time") || item->getUInt32Field("num") == 0))
			{
				continue;
			}
			uint32 cur_num = 0;
			item->setUInt32Field("num", cur_num);
			item->setUInt32Field("handle_time", time(0));
			item->SaveDB();
			// 下发更新物品数量
			WorldPacket newP;
			if(sProtocolsMgr.CreateUpdateItemNumberPacket(&newP, item->model->getHandle(), cur_num))
				SendProtocolsToChr(chr, &newP);
		}
	}
	return true;
}
//-----------------------------------------------------------------------
void GameLogicManager::MammonCome(CharPtr & chr, bool bPresend)
{
	if (chr.isNull() ||  chr->getUInt32Field("lv") < sXmlDataMgr.GetConfXMLValue("NEED_LV"))
		return;
	// 子游戏不送
	UserPtr pUser = sUserMgr.getByHandle(chr->getUInt32Field("userid"));
	if (pUser.isNull() || (bool)pUser->getUInt32Field("flag"))
		return;
	bool bCanSend = true;
	if (bPresend)
	{
		bCanSend = chr->getUInt32Field("lv") == sXmlDataMgr.GetConfXMLValue("NEED_LV");
	}
	else
	{
		list<ItemPtr> lstItems;
		chr->getItemsList(&lstItems);
		// 获取背包物品信息
		list<ItemPtr>::iterator iter = lstItems.begin(), iterEnd = lstItems.end();
		for(; iter !=iterEnd; ++iter)
		{
			ItemPtr item = *iter;
			if(item->getItemStatus() == Item::ItemStatusDeleted)
				continue;
			ItemModelPtr & model = item->model;
			if(model.isNull())
				continue;
			if (model->getUInt32Field("type") == 1 && model->getUInt32Field("sub_type") == 1) // 找到财神卡
			{
				bCanSend = false;
				break;
			}
		}
	}
	if (bCanSend)
	{
		AddMammonCard(chr, ItemModel_Mammon, 1);
	}
}
//-----------------------------------------------------------------------
bool GameLogicManager::BeHadMammonCard(CharPtr & chr)
{
	if (chr.isNull())
		return false;
	list<ItemPtr> lstItems;
	chr->getItemsList(&lstItems);
	// 获取背包物品信息
	list<ItemPtr>::iterator iter = lstItems.begin(), iterEnd = lstItems.end();
	for(; iter !=iterEnd; ++iter)
	{
		ItemPtr item = *iter;
		if(item->getItemStatus() == Item::ItemStatusDeleted)
			continue;
		ItemModelPtr & model = item->model;
		if(model.isNull())
			continue;
		if (model->getUInt32Field("type") == 1 && model->getUInt32Field("sub_type") == 1 && item->getUInt32Field("num") > 0) // 找到财神卡
		{
			return true;
		}
	}
	return false;
}
//-----------------------------------------------------------------------
void GameLogicManager::TouchLuckyCard(CharPtr & chr, int32 winCoins)
{
	if (chr.isNull() || winCoins <= 0)
		return;
	ItemPtr pItem;
	GetLuckCard(chr, pItem);
	if (pItem.isNull())
		return;
	uint32 maxPoint = pItem->model->getUInt32Field("maxhp"); // 单次上限点数
	uint32 leftPoint = pItem->getUInt32Field("num"); // 当前剩余点数
	uint32 realPoint = leftPoint > maxPoint ? maxPoint : leftPoint;	// 真实可用点数
	if ((uint32)winCoins < realPoint)
	{
		realPoint = winCoins;
	}
	pItem->setUInt32Field("num", leftPoint - realPoint);
	pItem->SaveDB();
	uint32 purview = pItem->model->getUInt32Field("max_num"); // 总权重
	uint32 curPurView = RandomUInt(0, purview-1);
	float multiple = 0.0f;
	uint32 tempPur = uint32(pItem->model->getFloatField("range_x2") * purview);
	bool bNotice = false;
	if (curPurView < tempPur)
	{
		multiple = pItem->model->getFloatField("range_x1");
		bNotice = pItem->model->getFloatField("offset_x") > 0;
	}
	else 
	{
		tempPur += uint32(pItem->model->getFloatField("range_y2") * purview);
		if (curPurView < tempPur)
		{
			multiple = pItem->model->getFloatField("range_y1");
			bNotice = pItem->model->getFloatField("offset_y") > 0;
		}
		else
		{
			multiple = pItem->model->getFloatField("range_z1");
			bNotice = pItem->model->getFloatField("offset_z") > 0;
		}
	}
	uint32 addCoins = uint32(realPoint * multiple);
	char msg[256];
	if (bNotice)
	{
		sprintf(msg, sMsg.getMessage("lucky_notice").c_str(), chr->getStringField("name2").c_str(), realPoint, multiple, addCoins);
		String strMsg(msg);
		SendNotice(strMsg, sMsg.getType("lucky_notice"));
	}
	// 通知玩家得到额外奖励
	uint32 modelId = pItem->model->getHandle();
	WorldPacket packet;
	if(sProtocolsMgr.CreateUsedLuckyCardPacket(&packet, modelId, realPoint, multiple, addCoins))
		SendProtocolsToChr(chr, &packet);
	// 消息提示
	memset(msg, 0, sizeof(msg));
	sprintf(msg, sMsg.getMessage("lucky_card").c_str(), realPoint, addCoins);
	SendSystemMessage(chr, msg, sMsg.getType("lucky_card"));
	// 更新幸运点数
	if(sProtocolsMgr.CreateUpdateItemNumberPacket(&packet, pItem->model->getHandle(), pItem->getUInt32Field("num")))
		SendProtocolsToChr(chr, &packet);
	
	// 添加额外的钱
	addItemNum(chr, ItemModel_Coins, addCoins);
	// 记录幸运卡增加铜钱日志
	sLogDataMgr.UpdateItemsInfoLog(chr, en_ST_Item, ItemModel_Coins, en_UNT_Add, addCoins, modelId, realPoint, uint32(multiple));
	// 记录扣除幸运卡点数日志
	sLogDataMgr.UpdateItemsInfoLog(chr, en_ST_Item, modelId, en_UNT_Reduce, realPoint, modelId);
	
	AddLuckyCardExps(chr,pItem->model->getHandle(),realPoint);
	
	if(sProtocolsMgr.CreateCharSpecificPacket(&packet,chr->getHandle(),en_CharSpecific_LuckyStar,uint32(multiple),addCoins))
	{
		AICreatureBaseInterface * pChrInter = TO_CREATURE_BASE_INTERFACE(chr->getAIInterface());
		if(pChrInter == NULL)
			return ;
		
		ChannelPtr pChannel = pChrInter->GetChannelPtr(); 
		if(pChannel.isNull())
			return ;
		AIChannelBaseInterface *pAiChanInfe = TO_CHANNEL_BASE_INTERFACE(pChannel->getAIInterface());
		if (pAiChanInfe == NULL)
			return;
		
		pAiChanInfe->BroadcastPacket(&packet, false);
	}
}
//-----------------------------------------------------------------------
void GameLogicManager::GetLuckCard(CharPtr & chr, ItemPtr & luckCard)
{
	if (chr.isNull())
		return;
	list<ItemPtr> lstItems;
	chr->getItemsList(&lstItems);
	// 获取背包物品信息
	list<ItemPtr>::iterator iter = lstItems.begin(), iterEnd = lstItems.end();
	for(; iter !=iterEnd; ++iter)
	{
		ItemPtr item = *iter;
		if(item->getItemStatus() == Item::ItemStatusDeleted)
			continue;
		ItemModelPtr & model = item->model;
		if(model.isNull())
			continue;
		if (model->getUInt32Field("type") == 2 && model->getUInt32Field("sub_type") == 1 && item->getUInt32Field("num") > 0) // 找到幸运卡
		{
			if (luckCard.isNull() || luckCard->model->getHandle() < model->getHandle())
			{
				luckCard = item;
			}
		}
	}
}
//-----------------------------------------------------------------------
void GameLogicManager::GetLuckCardList(CharPtr & chr, std::list<ItemPtr> &lstLucks)
{
	if (chr.isNull())
		return;
	list<ItemPtr> lstItems;
	chr->getItemsList(&lstItems);
	// 获取背包物品信息
	list<ItemPtr>::iterator iter = lstItems.begin(), iterEnd = lstItems.end();
	for(; iter !=iterEnd; ++iter)
	{
		ItemPtr item = *iter;
		if(item->getItemStatus() == Item::ItemStatusDeleted)
			continue;
		ItemModelPtr & model = item->model;
		if(model.isNull())
			continue;
		if (model->getUInt32Field("type") == 2 && model->getUInt32Field("sub_type") == 1 && item->getUInt32Field("num") > 0) // 找到幸运卡
		{
			lstLucks.push_back(item);
		}
	}
}

// 增加幸运卡经验值
void GameLogicManager::AddLuckyCardExps(CharPtr & pChr,const uint32 & model_id,uint32 & num)
{
	if(pChr.isNull())
		return ;
	
	AICreatureBaseInterface * pChrAiInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(!pChrAiInfe)
		return ;
	
	uint32 curExps = 0;
	uint32 exps_org = pChrAiInfe->GetXMLData("LUCKY_EXPS");
	uint8 lv = sVipCardMgr.GetCurrentLuckyLevel(exps_org,curExps);
	if(lv >= sVipCardMgr.GetLuckyExpMaxLevel())	//超过最大经验值
		return ;
	
	uint32 curr_exps = pChrAiInfe->GetXMLData("LUCKY_CURR_EXPS");
	curr_exps += num;
	
	bool bSave = false;
	uint32 lucky_changePer = sXmlDataMgr.GetConfXMLValue("SMALLLUCKY_CHANGE_EXPS");
	if(model_id == ItemModel_Luck3)
		lucky_changePer = sXmlDataMgr.GetConfXMLValue("SUPERLUCKY_CHANGE_EXPS");
	else if(model_id == ItemModel_Luck2)
		lucky_changePer = sXmlDataMgr.GetConfXMLValue("BIGLUCKY_CHANGE_EXPS");
	
	if(curr_exps >= lucky_changePer)
	{
		exps_org += (curr_exps / lucky_changePer);
		curr_exps %= lucky_changePer;
		bSave = true;
	}
	
	pChrAiInfe->SetXMLData("LUCKY_EXPS",exps_org);
	pChrAiInfe->SetXMLData("LUCKY_CURR_EXPS",curr_exps);
	
	if(bSave)
		pChr->SaveDB();
	
	WorldPacket packet;
	if(sVipCardMgr.CreateUpdateVipDataPacket(&packet,pChr))
		SendProtocolsToChr(pChr,&packet);
	
	Log.Notice("AddLuckyCardExps","pChr[%s] lv[%u] curr_exps[%u]",pChr->getCharName().c_str(),exps_org,curr_exps);
}

//-----------------------------------------------------------------------
void GameLogicManager::PacketPlayerSameInfo(WorldPacket * pPacket, CharPtr & pChr)
{
	if (pChr.isNull() || pPacket == NULL)
		return;
	if (pChr->isNPC())
	{
		AppendPacketString<uint8>(pPacket, ""); // ip真实地址
	}
	else
	{
		UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid")); 
		if (pUser.isNull())
			return;
		AppendPacketString<uint8>(pPacket, pUser->getStringField("addr")); // ip真实地址
	}
}

//-----------------------------------------------------------------------
void GameLogicManager::CreateMaJonMissionsToChar(CharPtr & pChr,std::vector<MaJonMission> * pMissions,const uint8 offset_value)
{
	if(pChr.isNull())
		return ;
	
	pMissions->clear();
	
	for(uint8 i=1; i<=3; ++i)
	{
		MaJonMission mission = sXmlDataMgr.CreateMaJonMission(i,offset_value);
		if(mission.model_id == 0)
			continue;
		
		pMissions->push_back(mission);
	}
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateMaJonMissionListPacket(&packet,*pMissions))
		SendProtocolsToChr(pChr,&packet);
}

//-----------------------------------------------------------------------
void GameLogicManager::FinishMaJonMission(CharPtr & pChr,MaJonMission & mission)
{
	if(pChr.isNull())
		return ;
	
	uint32 coins = mission.coins;
	uint32 hongbao = mission.hongbao;
	uint32 model_id = mission.model_id;
	
	if(coins)
	{
		addItemNum(pChr,ItemModel_Coins,coins);
		sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Task, ItemModel_Coins, en_UNT_Add, coins, model_id);
	}
	
	if(hongbao)
	{
		addItemNum(pChr,ItemModel_Lottery,hongbao);
		sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Task, ItemModel_Lottery, en_UNT_Add, hongbao, model_id);
	}
	
	mission.status = en_MajonMission_Finish;
	
	std::vector<MaJonMission> missions;
	missions.push_back(mission);
	
	char msg[256]="";
	sprintf(msg,sMsg.getMessage("finish_mission").c_str(),hongbao);
	SendSystemMessage(pChr, msg, sMsg.getType("finish_mission"));
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateMaJonMissionListPacket(&packet,missions))
		SendProtocolsToChr(pChr,&packet);
	
}
//-----------------------------------------------------------------------
bool 	GameLogicManager::NewPlayerSubsidy(CharPtr & pChr, bool isInstant)
{
	// 判断是否有领救济资格
	if (pChr.isNull())
		return false;
	// 等级限制
	uint32 needlv = sXmlDataMgr.GetConfXMLValue("SUBSIDY_LV");
	if (needlv && pChr->getUInt32Field("lv") >= needlv)
		return false;
	// 当前金额
	uint32 currcoins = sGLMgr.GetItemTotalNum(pChr, en_ItemModelId_Coins);
	uint32 sill = sXmlDataMgr.GetConfXMLValue("SILL_COINS");	// 触底金额	
	if (currcoins > sill)
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return false;
	// 取银行数据
	GameBank bank;
	if (!sBankMgr.GetRealBank(pUser, bank))
		return false;
	WorldPacket packet;
	if (bank.coins + currcoins > sill)
	{// 发送系统消息
		char str[512] = "";
		sprintf(str, sMsg.getMessage("SUBSIDY_MSG2").c_str(), bank.coins);
		sGLMgr.SendSystemMessage(pChr, str, sMsg.getType("SUBSIDY_MSG2"));	
		if (sProtocolsMgr.CreateTellToDoPacket(&packet, en_RemindType_GetBank))
			SendProtocolsToChr(pChr, &packet);
		return false;
	}
		
	uint32 subsidynum = sXmlDataMgr.GetConfXMLValue("SUBSIDY_NUM");// 补助次数	
	uint32 addcoins = sXmlDataMgr.GetConfXMLValue("SUBSIDY_COINS");// 补助金额
	uint32 basecoins = addcoins;
	time_t nowtime = time(0);
	if (!sTools.IsSameDate((time_t)bank.data8, nowtime))
	{
		bank.data7 = 0;
		bank.data8 = nowtime;
	}
	// 当日补助已经用完
	if ((uint32)bank.data7 >= subsidynum)
	{
		// 提醒充值		
		if (sProtocolsMgr.CreateTellToDoPacket(&packet, en_RemindType_BuyCoins))
			SendProtocolsToChr(pChr, &packet);
		return false;
	}
	// 达到补助标准,补钱
	sVipCardMgr.AppendSubsidyGift(pChr, addcoins);	// 附加VIP救济加成
	if (isInstant)
	{
		sGLMgr.addItemNum(pChr, en_ItemModelId_Coins, addcoins);	
		sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Hortation, ItemModel_Coins, en_UNT_Add, addcoins, en_HSI_Jackeroo);
		bank.data7 ++;
		bank.data8 = nowtime;
		// 发送系统消息
		char str[512] = "";
		sprintf(str, sMsg.getMessage("SUBSIDY_MSG1").c_str(), addcoins, subsidynum - bank.data7);
		sGLMgr.SendSystemMessage(pChr, str, sMsg.getType("SUBSIDY_MSG1"));
		return CenterDatabase.WaitExecute("update game_bank set `data7`=%u, `data8`=%u where bank_id = %u", \
				 bank.data7, bank.data8, bank.bank_id);
	}
	else if (sProtocolsMgr.CreateTellToDoPacket(&packet, en_RemindType_Subsidy, addcoins, uint32(subsidynum-bank.data7), basecoins, (addcoins - basecoins)))
		SendProtocolsToChr(pChr, &packet);
	
	return true;
}
//-----------------------------------------------------------------------
String GameLogicManager::GetMsgData(char* key, UserPtr &pUser)
{
	if (pUser.isNull())
	{
		return "";
	}
	String strKey(key);
	switch (pUser->getUInt32Field("country_id"))
	{
		case en_Language_Chinese:
			strKey += "_zh";
			break;
		case en_Language_English:
			strKey += "_en";
			break;
		default:
			strKey += "_zh";
			break;
	}
	return sMsg.getMessage(strKey);
}
//-----------------------------------------------------------------------
uint32 GameLogicManager::GetMsgType(char* key, UserPtr &pUser)
{
	if (pUser.isNull())
	{
		return 0;
	}
	String strKey(key);
	switch (pUser->getUInt32Field("country_id"))
	{
		case en_Language_Chinese:
			strKey += "_zh";
			break;
		case en_Language_English:
			strKey += "_en";
			break;
		default:
			strKey += "_zh";
			break;
	}
	return sMsg.getType(strKey);
}
//-----------------------------------------------------------------------
bool GameLogicManager::NoticeWelfare(CharPtr & pChr)
{	
	if (pChr.isNull())
		return false;
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull()/*  || pUser->getUInt32Field("flag") */)
		return false;
	
	GameBank bank;
	sBankMgr.GetPublicData(pUser, &bank);
	uint32 nowtime = time(0);
	
	WSSocketPtr pSocket = pChr->getSocket();
	if (pSocket.isNull())
		return false;
	std::list<VIPCard> lstWelfare;
	if (!sVipCardMgr.GetSelfWelfareList(pChr, lstWelfare))
		return false;
	std::list<VIPCard>::iterator iter, enditer = lstWelfare.end();
	for (iter = lstWelfare.begin(); iter != enditer; ++ iter)
	{
		uint32 *pEndTime = pChr->user_data.Get<uint32>((*iter).key);
		if (pEndTime == NULL)
			continue;
		
		uint8 status = 2;
		uint8 type = en_NGB_Welfare;
		if((*iter).id == 523)
		{
			type = en_RemindType_WeekCard;
			uint32 last_welfaretime = sBankMgr.GetUserDataVal(bank, "FLZHOULB");
			if (!sTools.IsSameDay(last_welfaretime, nowtime))
				status = 1;
		}
		else if((*iter).id == 524)
		{
			type = en_RemindType_MonthCard;
			uint32 last_welfaretime = sBankMgr.GetUserDataVal(bank, "FLYUELB");
			if (!sTools.IsSameDay(last_welfaretime, nowtime))
				status = 1;
		}
		
		if(*pEndTime < nowtime)
			status = 0;	// 可购买
		
		WorldPacket newP;
		// 操作类型 时间 状态（0 可购买 1 可领 2 已领）
		if (sProtocolsMgr.CreateTellToDoPacket(&newP, type, *pEndTime, status))
			pSocket->SendPacket(&newP);
	}
	
	return true;
}
//-----------------------------------------------------------------------
bool GameLogicManager::GainWelfare(CharPtr & pChr)
{
	if (!sVipCardMgr.HaveWelfare(pChr))
		return false;
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return false;
	time_t nt = time(0);
	GameBank bank;
	sBankMgr.GetPublicData(pUser, &bank);
	uint32 last_welfaretime = sBankMgr.GetUserDataVal(bank, "FLXZLB");
	if (sTools.IsSameDay(last_welfaretime, nt))
		return false;
	// 标记领取日期
	sBankMgr.SetUserDataVal(bank, "FLXZLB", nt);
	sBankMgr.SaveUserDataDB(bank);
	
	std::list<VIPCard> lstWelfare;
	uint32 allCoins = sVipCardMgr.GetSelfWelfareList(pChr, lstWelfare);
	if (allCoins)
	{		
		sGLMgr.addItemNum(pChr, ItemModel_Coins, allCoins);
		sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Hortation, ItemModel_Coins, en_UNT_Add, allCoins, en_HSI_Welfare);
		char str[512] = "";
		sprintf(str, sMsg.getMessage("WELFARE_MSG").c_str(), allCoins);
		sGLMgr.SendSystemMessage(pChr, str);		
		return true;
	}
	return false;
}

//-----------------------------------------------------------------------
bool GameLogicManager::GainSubsidyCard(CharPtr & pChr)
{	
	if (pChr.isNull())
		return false;
	WSSocketPtr pSocket = pChr->getSocket();
	if (pSocket.isNull())
		return false;
	ItemModelPtr pModel = sItemModelMgr.load(ItemModel_Subsidy);
	if (pModel.isNull())
		return false;
	WorldPacket newP;
	uint32 valve = pModel->getUInt32Field("max_num");
	uint32 allCoins = GetAllNum(pChr, ItemModel_Coins);
	if (allCoins > valve)
	{
		SendSystemMessage(pChr, sMsg.getMessage("subsidy_error").c_str(), sMsg.getType("subsidy_error"));
		if (sProtocolsMgr.CreateUserGainPacket(&newP, en_NGB_Subsidy, 0))
			pSocket->SendPacket(&newP);
		return false;	
	}
	if (!reduceItemNum(pChr, ItemModel_Subsidy, 1))
		return false;
	sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Hortation, ItemModel_Subsidy, en_UNT_Reduce, 1, en_NGB_Subsidy);
	uint32 addCoins = pModel->getUInt32Field("maxhp");
	addItemNum(pChr, ItemModel_Coins, addCoins);
	sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Hortation, ItemModel_Coins, en_UNT_Add, addCoins, en_NGB_Subsidy);	
	char pStr[512] = "";
	sprintf(pStr, sMsg.getMessage("subsidy_card").c_str(), addCoins, GetItemNum(pChr, ItemModel_Subsidy));	
	SendSystemMessage(pChr, pStr, sMsg.getType("subsidy_card"));	
	if (sProtocolsMgr.CreateUserGainPacket(&newP, en_NGB_Subsidy, addCoins))
		pSocket->SendPacket(&newP);
	return true;
}

// 领取周卡月卡
bool GameLogicManager::GainWeekMonthCard(CharPtr & pChr, const uint8 & type)
{
	if(pChr.isNull())
		return false;
	
	if (!sVipCardMgr.HaveWelfare(pChr))
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if (pUser.isNull())
		return false;
	
	time_t nt = time(0);
	GameBank bank;
	sBankMgr.GetPublicData(pUser, &bank);
	
	if(type == 1)
	{// 周卡
		uint32 last_weektime = sBankMgr.GetUserDataVal(bank, "FLZHOULB");
		if (sTools.IsSameDay(last_weektime, nt))
			return false;
		
		// 标记领取日期
		sBankMgr.SetUserDataVal(bank, "FLZHOULB", nt);
		sBankMgr.SaveUserDataDB(bank);
		
		std::list<VIPCard> lstWelfare;
		sVipCardMgr.GetSelfWelfareList(pChr, lstWelfare);
		
		uint32 addCoins = 0;
		uint32 endTime = 0;
		std::list<VIPCard>::iterator iter, ei = lstWelfare.end();
		for(iter = lstWelfare.begin(); iter!=ei; ++iter)
		{
			if (pChr->user_data.Get<uint32>("VIP_WEEKCARD", endTime) && endTime > 0)
			{
				addCoins = (*iter).lgAdd;
				break;
			}
		}
		
		if (addCoins)
		{
			sGLMgr.addItemNum(pChr, ItemModel_Coins, addCoins);
			sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Hortation, ItemModel_Coins, en_UNT_Add, addCoins, en_HSI_WeekCardActivity);
			char str[512] = "";
			sprintf(str, sMsg.getMessage("WELFARE_MSG").c_str(), addCoins);
			sGLMgr.SendSystemMessage(pChr, str);		
			
			// 发送已领取
			WorldPacket packet;
			if (sProtocolsMgr.CreateTellToDoPacket(&packet, en_RemindType_WeekCard, endTime, 2))
				SendProtocolsToChr(pChr, &packet);
			if (sProtocolsMgr.CreateUserGainPacket(&packet, en_NGB_WelfareWeek, ItemModel_Coins, addCoins))
				SendProtocolsToChr(pChr, &packet);
			return true;
		}
	}
	else if(type == 2)
	{// 月卡
		uint32 last_weektime = sBankMgr.GetUserDataVal(bank, "FLYUELB");
		if (sTools.IsSameDay(last_weektime, nt))
			return false;
		
		// 标记领取日期
		sBankMgr.SetUserDataVal(bank, "FLYUELB", nt);
		sBankMgr.SaveUserDataDB(bank);
		
		std::list<VIPCard> lstWelfare;
		sVipCardMgr.GetSelfWelfareList(pChr, lstWelfare);
		
		uint32 addCoins = 0;
		uint32 endTime = 0;
		
		std::list<VIPCard>::iterator iter, ei = lstWelfare.end();
		for(iter = lstWelfare.begin(); iter!=ei; ++iter)
		{
			if (pChr->user_data.Get<uint32>("VIP_MONTHCARD", endTime) && endTime > 0)
			{
				addCoins = (*iter).lgAdd;
				break;
			}
		}
		
		if (addCoins)
		{
			sGLMgr.addItemNum(pChr, ItemModel_Coins, addCoins);
			sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Hortation, ItemModel_Coins, en_UNT_Add, addCoins, en_HSI_MonthCardActivity);
			char str[512] = "";
			sprintf(str, sMsg.getMessage("WELFARE_MSG").c_str(), addCoins);
			sGLMgr.SendSystemMessage(pChr, str);
			
			WorldPacket packet;
			if (sProtocolsMgr.CreateTellToDoPacket(&packet, en_RemindType_MonthCard, endTime, 2))
				SendProtocolsToChr(pChr, &packet);
			if (sProtocolsMgr.CreateUserGainPacket(&packet, en_NGB_WelfareMonth, ItemModel_Coins, addCoins))
				SendProtocolsToChr(pChr, &packet);
			return true;
		}
	}
	else
	{
		return false;
	}
	
	return true;
}

//产生乐卡
bool GameLogicManager::CreateLECards(std::list<GameExchange> * cards,const uint32 & pid,const uint32 & cardsNum,const uint32 & cardsType,const uint32 & days)
{
	if(!cardsNum || !days)
		return false;
	
	cards->clear();
	
	char cType = 'G';	//卡类型
	if(cardsType == 2)
	{
		cType = 'S';
	}
	else if(cardsType == 3)
	{
		cType = 'C';
	}
	
	uint32 now_time = time(0);
	time_t over_time = now_time + days * 86400;
	over_time = sTools.FormatDataCeil(over_time);	
	String strYMD = "";
	
	tm overTm = *localtime(&over_time);	//结束时间
	strYMD = strYMD + ((overTm.tm_year % 100) >= 10 ? StringConverter::toString(overTm.tm_year % 100) : "0" + StringConverter::toString(overTm.tm_year % 100));
	strYMD = strYMD + ((overTm.tm_mon % 100) >= 9 ? StringConverter::toString(overTm.tm_mon % 100 + 1) : "0" + StringConverter::toString(overTm.tm_mon % 100 + 1));
	strYMD = strYMD + ((overTm.tm_mday % 100) >= 10 ? StringConverter::toString(overTm.tm_mday % 100) : "0" + StringConverter::toString(overTm.tm_mday % 100));
	
	CMD5 md5;
	String strPid = StringConverter::toString(pid);
	String szPid = md5.GenerateMD5(strPid.c_str());
	String fkgame = "RRGAME";
	
	uint32 curr_num = 0;
	uint32 realover_time = mktime(&overTm);
	for(uint8 i=0; i<cardsNum; ++i)
	{
		GameExchange * pEx = sItemMgr.newDumyExchange();
		if(!pEx)
			continue;
		
		pEx->status = enExchangeStataus_Process;
		pEx->group_id = 1;
		pEx->source = pid;	//生成与那个PID
		pEx->create_time = GetCurDateTime(now_time);	//创建时间
		pEx->end_time = GetCurDateTime(realover_time);	//到期时间
		
		pEx->data1 = now_time;							//创建时间
		pEx->data2 = realover_time;						//到期时间
		pEx->item_model1 = cardsType;					//类型
		pEx->item_id1 = 80 + (3 - cardsType) * 5;		//折扣率
		
		uint32 uint_key = now_time;
		uint_key ^= 0xC3;
		String transKey = StringConverter::toString(uint_key) + StringConverter::toString(i) + StringConverter::toString(pid) + StringConverter::toString(cardsType);
		String token = szPid + transKey + fkgame;
		String md5Str = md5.GenerateMD5(token.c_str());	
		
		String str1 = md5Str.substr(0,4);
		String str2 = md5Str.substr(4,4);
		String str3 = md5Str.substr(8,4);
		String str4 = md5Str.substr(12,4);
		
		char buf[256] = "";
		sprintf(buf,"%c-%s-%s-%s-%s-%s",cType,strYMD.c_str(),str1.c_str(),str2.c_str(),str3.c_str(),str4.c_str());
		
		pEx->token = buf;
		pEx->exchange_id = sItemMgr.createExchangeDB(pEx);
		
		//创建日志
		sBankMgr.LeMaOpLog(pid,en_LMOM_Create,pEx->exchange_id);
		
		cards->push_back(*pEx);
		sItemMgr.freeDumyExchange(pEx);
		
		++curr_num;
		if(curr_num && (curr_num % 10 == 0))
		{
			Sleep(50);
		}
		
	}
	
	return true;
}

// 检测过期乐码
void GameLogicManager::CheckTimeOverLeCards(const uint32 & pid)
{
	if(!pid)
		return ;
	
	uint32 now_time = time(0);
	uint32 count = sItemMgr.getExchangeDBCount("(source = %u and data3 = 0 and (status = %u or status = %u) )",
													pid,enExchangeStataus_Process,enExchangeStataus_YanZheng);
	if(!count)
		return ;
	
	std::list<GameExchange> exchanges;
	if(!sItemMgr.getExchangeListDB(&exchanges,0,count,"(source = %u and data3 = 0 and (status = %u or status = %u) )",
												pid,enExchangeStataus_Process,enExchangeStataus_YanZheng))
		return ;
	
	if(exchanges.empty())
		return ;
	
	std::list<GameExchange>::iterator iter,ei = exchanges.end();
	for(iter = exchanges.begin(); iter!=ei; ++iter)
	{
		if((*iter).data2 > now_time)	//还未过期
			continue;
		
		sBankMgr.LeMaOpLog(pid,en_LMOM_TimeOver,(*iter).exchange_id);
		(*iter).status = enExchangeStataus_TimeOver;
		sItemMgr.updateExchangeDB(&(*iter));
	}
}

//玩家投币
uint32 GameLogicManager::PutCoins(CharPtr & pChr,const uint32 & token_num)
{
	if(pChr.isNull() || !token_num)
		return 0;
	
	uint32 curr_score = sGLMgr.GetItemNum(pChr,ItemModel_Score);
	uint32 real_token = sGLMgr.GetItemNum(pChr,ItemModel_Token);
	if(real_token < token_num)
		return 0;
	
	uint32 get_score = token_num * sXmlDataMgr.GetConfXMLValue("LEBI_TO_SCORE");
	if(sGLMgr.reduceItemNum(pChr,ItemModel_Token,token_num))
	{
		sLogDataMgr.UpdateItemsInfoLog(pChr,en_ST_NormalExchange,ItemModel_Token,en_UNT_Reduce,token_num);	//扣乐币日志
		
		curr_score += get_score;
		sGLMgr.addItemNum(pChr,ItemModel_Score,get_score);
		
		sLogDataMgr.UpdateItemsInfoLog(pChr,en_ST_NormalExchange,ItemModel_Score,en_UNT_Add,token_num);	//加积分日志
	}
	
	return curr_score;
}

//玩家积分换钱
uint32 GameLogicManager::ChangeCoins(CharPtr & pChr,const uint32 & score)
{
	if(pChr.isNull() || !score)
		return 0;
	
	uint32 coins = sGLMgr.GetItemNum(pChr,ItemModel_Coins);
	uint32 real_score = sGLMgr.GetItemNum(pChr,ItemModel_Score);
	if(real_score < score)
		return real_score;
	
	uint32 get_coins = score * sXmlDataMgr.GetConfXMLValue("SCORE_TO_COINS");
	if(sGLMgr.reduceItemNum(pChr,ItemModel_Score,score))
	{
		sLogDataMgr.UpdateItemsInfoLog(pChr,en_ST_NormalExchange,ItemModel_Score,en_UNT_Reduce,score);	//扣积分日志
		
		coins += get_coins;
		sGLMgr.addItemNum(pChr,ItemModel_Coins,get_coins);
		
		sLogDataMgr.UpdateItemsInfoLog(pChr,en_ST_NormalExchange,ItemModel_Coins,en_UNT_Add,get_coins);	//加铜钱日志
	}
	
	return coins;
}
// 随机生成昵称
String GameLogicManager::GetNickWords()
{
	String nick = "贵宾";
	if (m_vecNicks.empty())
	{
		FILE* pfile = fopen("../scripts_xml/nick_words.txt", "r");
		if (pfile == NULL)
			return "";
		const int num = 50;
		char buffer[num] = {0};
		
		while(fgets(buffer, num, pfile))
		{
			//去掉换行
			char newbuffer[num] = {0};
			uint32 conuntNum = 0;
			while(buffer[conuntNum] != 13)
			{
				newbuffer[conuntNum] = buffer[conuntNum];
				++conuntNum;
			}
			newbuffer[conuntNum] = 0;			
			String nick = newbuffer;			
			m_vecNicks.push_back(nick);
			//清除BUFFER
			memset(buffer, 0, num);
		}		
		fclose(pfile);
	}
	if (m_vecNicks.empty())
		return nick;
	uint32 index = RandomUInt(0, m_vecNicks.size()-1);	
	Log.Error("GameLogicManager Test", "GetNickWords index[%u]", index);
	return m_vecNicks[index];
}

String GameLogicManager::getConfigFromUrl(const String & url) 
{ 
	 CURL *curl_handle; 

	 ByteBuffer  chunk; 

	 curl_global_init(CURL_GLOBAL_ALL); 

	 /* init the curl session */ 
	 curl_handle = curl_easy_init(); 

	 /* specify URL to get */ 
	 curl_easy_setopt(curl_handle, CURLOPT_URL, url.c_str()); 

	 /* send all data to this function  */ 
	 // curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, WriteMemoryCallback); 

	 /* we pass our 'chunk' struct to the callback function */ 
	 curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, (void *)&chunk); 

	 /* some servers don't like requests that are made without a user-agent 
		field, so we provide one */ 
	 curl_easy_setopt(curl_handle, CURLOPT_USERAGENT, "AdouGameServer-Agent/1.0"); 

	 /* get it! */ 
	 curl_easy_perform(curl_handle); 

	 /* cleanup curl stuff */ 
	 curl_easy_cleanup(curl_handle); 

	 String temp; 

	 chunk >> temp;
	 return temp;
}

// 判断字符串是否存在表情字符
bool GameLogicManager::containerEmojiCharacter(String strSrc)
{
	for (uint32 i = 0; i < strSrc.length(); i++) 
	{
		if (isEmojiCharacter(strSrc.at(i)))
			return true;
	}

	return false;
}

// 判断字符是否表情字符
bool GameLogicManager::isEmojiCharacter(char character)
{
	
	/* bool isEmoji = false;
	if (0xd800 <= character && character <= 0xdbff) {
		if (source.length() > 1) {
			char ls = source.charAt(i+1);
			int uc = ((character - 0xd800) * 0x400) + (ls - 0xdc00) + 0x10000;
			if (0x1d000 <= uc && uc <= 0x1f77f) {
				return true;
			}
		}
	} else {
		// non surrogate
		if (0x2100 <= character && character <= 0x27ff && character != 0x263b) {
			return true;
		} else if (0x2B05 <= character && character <= 0x2b07) {
			return true;
		} else if (0x2934 <= character && character <= 0x2935) {
			return true;
		} else if (0x3297 <= character && character <= 0x3299) {
			return true;
		} else if (character == 0xa9 || character == 0xae || character == 0x303d || 
					character == 0x3030 || character == 0x2b55 || character == 0x2b1c || 
					character == 0x2b1b || character == 0x2b50|| character == 0x231a ) {
			return true;
		}
		if (!isEmoji && source.length() > 1 && i < source.length() -1) {
			char ls = source.charAt(i+1);
			if (ls == 0x20e3) {
				return true;
			}
		}
	}
	
	return isEmoji; */
	
	 return (character == 0x0) ||(character == 0x9) ||
                (character == 0xA) || (character == 0xD) ||
                ((character >= 0x20) && (character <= 0xD7FF)) ||
                ((character >= 0xE000) && (character <= 0xFFFD)) ||
                ((character >= 0x10000) && (character <= 0x10FFFF));
}

// 过滤掉表情字符
String GameLogicManager::filterEmoji(String source)
{
	 
	// String clean_text = "";
	// Match Emoticons
	// String regexEmoticons = "/[\x{1F600}-\x{1F64F}]/u";
	// clean_text = replace_all(source, regexEmoticons, "");
	/* // Match Miscellaneous Symbols and Pictographs
	$regexSymbols = '/[\x{1F300}-\x{1F5FF}]/u';
	$clean_text = preg_replace($regexSymbols, $replaceTo, $clean_text);
	// Match Transport And Map Symbols
	$regexTransport = '/[\x{1F680}-\x{1F6FF}]/u';
	$clean_text = preg_replace($regexTransport, $replaceTo, $clean_text);
	// Match Miscellaneous Symbols
	$regexMisc = '/[\x{2600}-\x{26FF}]/u';
	$clean_text = preg_replace($regexMisc, $replaceTo, $clean_text);
	// Match Dingbats
	$regexDingbats = '/[\x{2700}-\x{27BF}]/u';
	$clean_text = preg_replace($regexDingbats, $replaceTo, $clean_text);
	return $clean_text; */
	
	// source = ServerDatabase.EscapeString(source);
	// return source.replace_all(source, "/\\\u[ed][0-9a-f]{3}\\\u[ed][0-9a-f]{3}/", "");

	/* if (!containerEmojiCharacter(source))
		return source;//如果不包含，直接返回
	
	//到这里铁定包含
	String strResult = "";
	
	int len = source.length();
	for (int i = 0; i < len; i++)
	{
		char codePoint = source.at(i);

		if (!isEmojiCharacter(codePoint))
			strResult += codePoint;
	}

	if (strResult.length() == len) 
	{//这里的意义在于尽可能少的toString，因为会重新生成字符串
		return source;
	}
	else
	{
		return strResult;
	} */
	
	return "";
}

bool GameLogicManager::SendChannelDanMu(CharPtr & pChr,uint32 danmu_serial,uint16 pos,String content)
{
	if(pChr.isNull() || content == "")
		return false;
	
	stDanMu danMu,danMu_null;
	danMu.danmu_id = danmu_serial;
	danMu.char_id = pChr->getHandle();
	danMu.pos = pos;
	danMu.content = content;
	danMu.srcName = pChr->getCharName();
	danMu.isVip = sVipCardMgr.GetUsedVipId(pChr);
	
	AICreatureBaseInterface * pChrAiInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(!pChrAiInfe)
		return false;
	
	ChannelPtr chnPtr = pChrAiInfe->GetChannelPtr();
	if(chnPtr.isNull())
		return false;
	
	AIChannelBaseInterface * pChnAiInfe = TO_CHANNEL_BASE_INTERFACE(chnPtr->getAIInterface());
	if(!pChnAiInfe)
		return false;
	
	WorldPacket packet;
	
	//弹幕次数的判断（是否VIP）
	if(!danMu.isVip)
	{// 检测每日弹幕条数
		uint32 send_maxCount = sXmlDataMgr.GetConfXMLValue("MAX_DANMU_SEND_COUNT");
		uint32 curr_SendCount = pChrAiInfe->GetXMLData("TODAY_DANMU_SEND_COUNT");	//本日弹幕发送次数
		
		if(curr_SendCount >= send_maxCount)
		{// 本日发送次数以达上线
			if(sProtocolsMgr.CreateDanMuInfoPacket(&packet,danMu,enDanmuResult_TooMuchCount))
				sGLMgr.SendProtocolsToChr(pChr,&packet);
			return false;
		}
		else
		{// 增加发送次数
			pChrAiInfe->AddXMLValue("TODAY_DANMU_SEND_COUNT",1);
		}
	}
	
	uint32 channel_id = chnPtr->getHandle();
	uint32 limit_num = sXmlDataMgr.GetConfXMLValue("MAX_DANMU_COUNT");
	
	std::map<uint32,std::vector<stDanMu> >::iterator fit = m_mapDanMuChannelHistory.find(channel_id);
	if(fit ==m_mapDanMuChannelHistory.end())
	{
		std::vector<stDanMu> vDanMu;
		vDanMu.push_back(danMu);
		m_mapDanMuChannelHistory.insert(std::make_pair(channel_id,vDanMu));
	}
	else
	{
		fit->second.push_back(danMu);
		if(fit->second.size() >= limit_num)
			fit->second.erase(fit->second.begin());
	}
	
	if(sProtocolsMgr.CreateDanMuInfoPacket(&packet,danMu))
		pChnAiInfe->BroadcastPacket(&packet);
	
	return true;
}

bool GameLogicManager::SendTownDanMu(CharPtr & pChr,uint32 danmu_serial,uint16 pos,String content)
{
	if(pChr.isNull() || content == "")
		return false;
	
	return true;
}

void GameLogicManager::GetDanMuHistoryList(CharPtr & pChr,const uint8 & type)
{
	if(pChr.isNull())
		return ;
	
	AICreatureBaseInterface * pChrAiInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(pChrAiInfe)
		return ;
	
	std::vector<stDanMu> vDanMu;
	
	switch(type)
	{
	case enDanMuType_Channel:
		{
			ChannelPtr chnPtr = pChrAiInfe->GetChannelPtr();
			if(chnPtr.isNull())
				return ;
			
			std::map<uint32,std::vector<stDanMu> >::iterator fit = m_mapDanMuChannelHistory.find(chnPtr->getHandle());
			if(fit != m_mapDanMuChannelHistory.end())
				vDanMu = fit->second;
			
		}
		break;
	case enDanMuType_Town:
		{
			TownPtr pTown = pChrAiInfe->GetTown();
			if(pTown.isNull())
				return ;
			
			std::map<uint32,std::vector<stDanMu> >::iterator fit = m_mapDanMuTownHistory.find(pTown->getHandle());
			if(fit != m_mapDanMuTownHistory.end())
				vDanMu = fit->second;
			
		}
		break;
	default:
		break;
	}
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateDanMuHistoryPacket(&packet,vDanMu))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
}

// 重置某些数据
void GameLogicManager::resetSomeData(CharPtr & pChr)
{
	if(pChr.isNull())
		return ;
	
	// 重置每日发送弹幕数量
	AICreatureBaseInterface *pAIChar = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if (pAIChar)
		pAIChar->SetXMLData("TODAY_DANMU_SEND_COUNT",0);
}

//======================================================================================
bool GameLogicManager::BuildCommonJsonMission(CharPtr & pChr,std::list<ResourcePtr> missionModels,const uint8 & missionstyle)
{
	uint32 model_id = sXmlDataMgr.GetConfXMLValue("COMMON_JSONMISSION_MODELID");
	if(pChr.isNull() || !model_id || missionModels.empty())
		return false;
	
	// 找不到该任务模式
	MissionModelPtr missModel = sMissionModelMgr.load(model_id);
	if(missModel.isNull())
		return false;
	
	// 创建任务的玩家不在线
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	std::list<MissionPtr> myMissions;
	pChr->getMissionsList(&myMissions);
	
	MissionPtr pMission;
	for (std::list<MissionPtr>::iterator it=myMissions.begin(); it!=myMissions.end(); it++)
	{
		if ((*it)->model->getSerial() == model_id)
		{// 获得指定任务
			pMission = *it;
			break;
		}
	}
	
	Json::Value val;
	Json::Reader reader;
	
	if (pMission.isNull())
	{// 没找到任务，创建
		Resource* pNewMission = sMissionMgr.newDumyMission(model_id);
		pNewMission->setUInt32Field("mission_model_id", model_id);
		pNewMission->setUInt32Field("status", Mission::MissionStatusProcess);
		pNewMission->setUInt32Field("owner_id", pChr->getHandle());
		pNewMission->setUInt32Field("owner_type", pChr->getTargetType());
		pMission = sMissionMgr.loadMissionDatabase(pNewMission);
		sMissionMgr.freeDumyMission(pNewMission);
	}
	else
	{
		reader.parse(pMission->getStringField("require"), val);
		if(val.isMember("daily_missions") && missionstyle == enCommonMissionStyle_Daily)
		{// 刷新每日任务
			val["daily_missions"].clear();
		}
		
		if(val.isMember("forever_missions") && missionstyle == enCommonMissionStyle_Forever)
		{// 已经生成过永久任务了
			return false;
		}
	}
	
	uint32 time_now = time(0);
	
	char strMissStyle[256] = "";
	if(missionstyle == enCommonMissionStyle_Daily)
	{// 日常任务
		sprintf(strMissStyle,"%s","daily_missions");
	}
	else if(missionstyle == enCommonMissionStyle_Forever)
	{// 常驻任务
		sprintf(strMissStyle,"%s","forever_missions");
	}
	
	std::list<ResourcePtr>::iterator iter,ei = missionModels.end();
	for(iter = missionModels.begin(); iter!=ei; ++iter)
	{
		uint32 mission_modelID = (*iter)->getHandle();
		char str[12];
		sprintf(str, "%u", mission_modelID);
		
		val[strMissStyle][str]["ut"] = time_now;							//更新时间uptime
		val[strMissStyle][str]["n"] = 0;									//完成进度num
		val[strMissStyle][str]["t"] = (*iter)->getUInt32Field("data1");		//需求total
		val[strMissStyle][str]["s"] = enCommonMissionStatus_Process;		//任务状态status
		val[strMissStyle][str]["ft"] = 0;									//完成时间finishtime
		val[strMissStyle][str]["icon_id"] = (*iter)->getUInt32Field("icon");//图标ID
		val[strMissStyle][str]["name"] = (*iter)->getStringField("name");	//任务名称
		val[strMissStyle][str]["desc"] = (*iter)->getStringField("desc");	//任务描述
	}
	
	Json::FastWriter w;
	pMission->setStringField("require", w.write(val));
	pMission->SaveDB();
	return true;
}

//======================================================================================
bool GameLogicManager::AddMissionFinishCount(CharPtr & pChr,const uint32 & mission_type,const uint32 & count)
{
	if(pChr.isNull() || !mission_type || !count)
		return false;
	
	std::list<MissionPtr> missionList;
	pChr->getMissionsList(&missionList);
	
	if(missionList.empty())
		return false;
	
	uint32 model_id = sXmlDataMgr.GetConfXMLValue("COMMON_JSONMISSION_MODELID");
	if(!model_id)
		return false;
	
	MissionPtr pMission;
	for (std::list<MissionPtr>::iterator it=missionList.begin(); it!=missionList.end(); it++)
	{
		if ((*it)->model->getSerial() == model_id)
		{// 获得指定任务
			pMission = *it;
			break;
		}
	}
	
	Json::Value val;
	if (!pMission.isNull())
	{// 重置任务数据
		Json::Reader reader;
		reader.parse(pMission->getStringField("require"), val);
	}
	else
	{// 没找到任务
		return false;
	}
	
	bool bNeedWriting = false;
	WorldPacket packet;
	
	
	if(val.isMember("daily_missions"))
	{
		for (Json::Value::iterator iterVal=val["daily_missions"].begin(); iterVal!=val["daily_missions"].end(); ++iterVal)
		{
			uint32 missionModelID = StringConverter::parseUnsignedInt(iterVal.key().asString());
			MissionModelPtr modelPtr = sMissionModelMgr.load(missionModelID);
			if(modelPtr.isNull())
				continue;
			
			if(modelPtr->getUInt32Field("type") != mission_type)
				continue;
			
			// 未在进行中
			if((*iterVal)["s"].asUInt() != enCommonMissionStatus_Process)
				continue;
			
			uint32 complate_count = (*iterVal)["n"].asUInt() + count;
			uint32 max_num = modelPtr->getUInt32Field("data1");
			(*iterVal)["n"] = complate_count;
			
			if(complate_count >= max_num)
			{
				// 任务完成，更新任务状态
				(*iterVal)["s"] = enCommonMissionStatus_Finish;
				(*iterVal)["n"] = max_num;	
				(*iterVal)["ft"] = uint32(time(0));	
			}
			
			bNeedWriting = true;
			
			if(sProtocolsMgr.CreateCommonSingleJsonMissionPacket(&packet,modelPtr->getHandle(),
								(*iterVal)["s"].asUInt(),(*iterVal)["n"].asUInt(),max_num))
				sGLMgr.SendProtocolsToChr(pChr,&packet);
		}
	}
	else if(val.isMember("forever_missions"))
	{
		for (Json::Value::iterator iterVal=val["forever_missions"].begin(); iterVal!=val["forever_missions"].end(); ++iterVal)
		{
			uint32 missionModelID = StringConverter::parseUnsignedInt(iterVal.key().asString());
			MissionModelPtr modelPtr = sMissionModelMgr.load(missionModelID);
			if(modelPtr.isNull())
				continue;
			
			if(modelPtr->getUInt32Field("type") != mission_type)
				continue;
			
			// 未在进行中
			if((*iterVal)["s"].asUInt() != enCommonMissionStatus_Process)
				continue;
			
			uint32 complate_count = (*iterVal)["n"].asUInt() + count;
			uint32 max_num = modelPtr->getUInt32Field("data1");
			(*iterVal)["n"] = complate_count;
			
			if(complate_count >= max_num)
			{
				// 任务完成，更新任务状态
				(*iterVal)["s"] = enCommonMissionStatus_Finish;
				(*iterVal)["n"] = max_num;	
				(*iterVal)["ft"] = uint32(time(0));	
			}
			
			bNeedWriting = true;
			
			if(sProtocolsMgr.CreateCommonSingleJsonMissionPacket(&packet,modelPtr->getHandle(),
								(*iterVal)["s"].asUInt(),(*iterVal)["n"].asUInt(),max_num))
				sGLMgr.SendProtocolsToChr(pChr,&packet);
		}
	}
	
	if(bNeedWriting)
	{
		Json::FastWriter w;
		pMission->setStringField("require", w.write(val));
		pMission->SaveDB();
	}
	
	return true;
}

//======================================================================================
bool GameLogicManager::HasMissionCompalateAtValue(CharPtr & pChr,const uint32 & mission_type,const uint32 & value)
{
	if(pChr.isNull() || !mission_type || !value)
		return false;
	
	std::list<MissionPtr> missionList;
	pChr->getMissionsList(&missionList);
	
	if(missionList.empty())
		return false;
	
	uint32 model_id = sXmlDataMgr.GetConfXMLValue("COMMON_JSONMISSION_MODELID");
	if(!model_id)
		return false;
	
	MissionPtr pMission;
	for (std::list<MissionPtr>::iterator it=missionList.begin(); it!=missionList.end(); it++)
	{
		if ((*it)->model->getSerial() == model_id)
		{// 获得指定任务
			pMission = *it;
			break;
		}
	}
	
	Json::Value val;
	if (!pMission.isNull())
	{// 重置任务数据
		Json::Reader reader;
		reader.parse(pMission->getStringField("require"), val);
	}
	else
	{// 没找到任务
		return false;
	}
	
	bool bNeedWriting = false;
	WorldPacket packet;
	
	if(val.isMember("daily_missions"))
	{
		for (Json::Value::iterator iterVal=val["daily_missions"].begin(); iterVal!=val["daily_missions"].end(); ++iterVal)
		{
			uint32 missionModelID = StringConverter::parseUnsignedInt(iterVal.key().asString());
			MissionModelPtr modelPtr = sMissionModelMgr.load(missionModelID);
			if(modelPtr.isNull())
				continue;
			
			if(modelPtr->getUInt32Field("type") != mission_type)
				continue;
			
			// 未在进行中
			if((*iterVal)["s"].asUInt() != enCommonMissionStatus_Process)
				continue;
			
			uint32 max_num = modelPtr->getUInt32Field("data1");
			if(value >= max_num)
			{
				// 任务完成，更新任务状态
				(*iterVal)["s"] = enCommonMissionStatus_Finish;
				(*iterVal)["n"] = max_num;	
				(*iterVal)["ft"] = uint32(time(0));	
			}
			
			bNeedWriting = true;
			
			if(sProtocolsMgr.CreateCommonSingleJsonMissionPacket(&packet,modelPtr->getHandle(),
								(*iterVal)["s"].asUInt(),(*iterVal)["n"].asUInt(),max_num))
				sGLMgr.SendProtocolsToChr(pChr,&packet);
		}
	}
	else if(val.isMember("forever_missions"))
	{
		for (Json::Value::iterator iterVal=val["forever_missions"].begin(); iterVal!=val["forever_missions"].end(); ++iterVal)
		{
			uint32 missionModelID = StringConverter::parseUnsignedInt(iterVal.key().asString());
			MissionModelPtr modelPtr = sMissionModelMgr.load(missionModelID);
			if(modelPtr.isNull())
				continue;
			
			if(modelPtr->getUInt32Field("type") != mission_type)
				continue;
			
			// 未在进行中
			if((*iterVal)["s"].asUInt() != enCommonMissionStatus_Process)
				continue;
			
			uint32 max_num = modelPtr->getUInt32Field("data1");
			if(value >= max_num)
			{
				// 任务完成，更新任务状态
				(*iterVal)["s"] = enCommonMissionStatus_Finish;
				(*iterVal)["n"] = max_num;	
				(*iterVal)["ft"] = uint32(time(0));	
			}
			
			bNeedWriting = true;
			
			if(sProtocolsMgr.CreateCommonSingleJsonMissionPacket(&packet,modelPtr->getHandle(),
								(*iterVal)["s"].asUInt(),(*iterVal)["n"].asUInt(),max_num))
				sGLMgr.SendProtocolsToChr(pChr,&packet);
		}
	}
	
	if(bNeedWriting)
	{
		Json::FastWriter w;
		pMission->setStringField("require", w.write(val));
		pMission->SaveDB();
	}
	
	return true;
}

//======================================================================================
bool GameLogicManager::SetMissionCompalateAtValue(CharPtr & pChr,const uint32 & mission_type,const uint32 & count)
{
	if(pChr.isNull() || !mission_type || !count)
		return false;
	
	std::list<MissionPtr> missionList;
	pChr->getMissionsList(&missionList);
	
	if(missionList.empty())
		return false;
	
	uint32 model_id = sXmlDataMgr.GetConfXMLValue("COMMON_JSONMISSION_MODELID");
	if(!model_id)
		return false;
	
	MissionPtr pMission;
	for (std::list<MissionPtr>::iterator it=missionList.begin(); it!=missionList.end(); it++)
	{
		if ((*it)->model->getSerial() == model_id)
		{// 获得指定任务
			pMission = *it;
			break;
		}
	}
	
	Json::Value val;
	if (!pMission.isNull())
	{// 重置任务数据
		Json::Reader reader;
		reader.parse(pMission->getStringField("require"), val);
	}
	else
	{// 没找到任务
		return false;
	}
	
	bool bNeedWriting = false;
	WorldPacket packet;
	
	
	if(val.isMember("daily_missions"))
	{
		for (Json::Value::iterator iterVal=val["daily_missions"].begin(); iterVal!=val["daily_missions"].end(); ++iterVal)
		{
			uint32 missionModelID = StringConverter::parseUnsignedInt(iterVal.key().asString());
			MissionModelPtr modelPtr = sMissionModelMgr.load(missionModelID);
			if(modelPtr.isNull())
				continue;
			
			if(modelPtr->getUInt32Field("type") != mission_type)
				continue;
			
			// 未在进行中
			if((*iterVal)["s"].asUInt() != enCommonMissionStatus_Process)
				continue;
			
			uint32 max_num = modelPtr->getUInt32Field("data1");
			(*iterVal)["n"] = count;
			
			if(count >= max_num)
			{
				// 任务完成，更新任务状态
				(*iterVal)["s"] = enCommonMissionStatus_Finish;
				(*iterVal)["n"] = max_num;	
				(*iterVal)["ft"] = uint32(time(0));	
			}
			
			bNeedWriting = true;
			
			if(sProtocolsMgr.CreateCommonSingleJsonMissionPacket(&packet,modelPtr->getHandle(),
								(*iterVal)["s"].asUInt(),(*iterVal)["n"].asUInt(),max_num))
				sGLMgr.SendProtocolsToChr(pChr,&packet);
		}
	}
	else if(val.isMember("forever_missions"))
	{
		for (Json::Value::iterator iterVal=val["forever_missions"].begin(); iterVal!=val["forever_missions"].end(); ++iterVal)
		{
			uint32 missionModelID = StringConverter::parseUnsignedInt(iterVal.key().asString());
			MissionModelPtr modelPtr = sMissionModelMgr.load(missionModelID);
			if(modelPtr.isNull())
				continue;
			
			if(modelPtr->getUInt32Field("type") != mission_type)
				continue;
			
			// 未在进行中
			if((*iterVal)["s"].asUInt() != enCommonMissionStatus_Process)
				continue;
			
			uint32 max_num = modelPtr->getUInt32Field("data1");
			(*iterVal)["n"] = count;
			
			if(count >= max_num)
			{
				// 任务完成，更新任务状态
				(*iterVal)["s"] = enCommonMissionStatus_Finish;
				(*iterVal)["n"] = max_num;	
				(*iterVal)["ft"] = uint32(time(0));	
			}
			
			bNeedWriting = true;
			
			if(sProtocolsMgr.CreateCommonSingleJsonMissionPacket(&packet,modelPtr->getHandle(),
								(*iterVal)["s"].asUInt(),(*iterVal)["n"].asUInt(),max_num))
				sGLMgr.SendProtocolsToChr(pChr,&packet);
		}
	}
	
	if(bNeedWriting)
	{
		Json::FastWriter w;
		pMission->setStringField("require", w.write(val));
		pMission->SaveDB();
	}
	
	return true;
}

//======================================================================================
bool GameLogicManager::GetJsonMissionBounty(CharPtr & pChr,const uint32 & model_id)
{
	if(pChr.isNull() || !model_id)
		return false;
	
	std::list<MissionPtr> missionList;
	pChr->getMissionsList(&missionList);
	
	if(missionList.empty())
		return false;
	
	uint32 model_listid = sXmlDataMgr.GetConfXMLValue("COMMON_JSONMISSION_MODELID");
	if(!model_listid)
		return false;
	
	MissionPtr pMission;
	for (std::list<MissionPtr>::iterator it=missionList.begin(); it!=missionList.end(); it++)
	{
		if ((*it)->model->getSerial() == model_listid)
		{// 获得指定任务
			pMission = *it;
			break;
		}
	}
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(pMission->getStringField("require"), val);
	
	bool bNeedWriting = false;
	WorldPacket packet;
	
	if(val.isMember("daily_missions"))
	{
		for (Json::Value::iterator iterVal=val["daily_missions"].begin(); iterVal!=val["daily_missions"].end(); ++iterVal)
		{
			uint32 missionModelID = StringConverter::parseUnsignedInt(iterVal.key().asString());
			if(missionModelID != model_id)
				continue;
			
			MissionModelPtr modelPtr = sMissionModelMgr.load(missionModelID);
			if(modelPtr.isNull())
				continue;
			
			// 未达到完成状态的
			if((*iterVal)["s"].asUInt() != enCommonMissionStatus_Finish)
				continue;
			
			bNeedWriting = true;
			
			// 任务完成，更新任务状态为领取
			(*iterVal)["s"] = enCommonMissionStatus_GetBounty;
			
			// 发放任务奖励
			uint32 coins_num = modelPtr->getUInt32Field("data2");
			sGLMgr.addItemNum(pChr,ItemModel_Coins,coins_num);
			sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Task, ItemModel_Coins, en_UNT_Add, coins_num, model_id);
			// 更新任务状态
			if(sProtocolsMgr.CreateCommonSingleJsonMissionPacket(&packet,modelPtr->getHandle(),
								(*iterVal)["s"].asUInt(),(*iterVal)["n"].asUInt(),(*iterVal)["n"].asUInt()))
				sGLMgr.SendProtocolsToChr(pChr,&packet);
		}
	}
	else if(val.isMember("forever_missions"))
	{
		for (Json::Value::iterator iterVal=val["forever_missions"].begin(); iterVal!=val["forever_missions"].end(); ++iterVal)
		{
			uint32 missionModelID = StringConverter::parseUnsignedInt(iterVal.key().asString());
			if(missionModelID != model_id)
				continue;
			
			MissionModelPtr modelPtr = sMissionModelMgr.load(missionModelID);
			if(modelPtr.isNull())
				continue;
			
			// 未达到完成状态的
			if((*iterVal)["s"].asUInt() != enCommonMissionStatus_Finish)
				continue;
			
			bNeedWriting = true;
			
			// 任务完成，更新任务状态为领取
			(*iterVal)["s"] = enCommonMissionStatus_GetBounty;
			
			// 发放任务奖励
			uint32 coins_num = modelPtr->getUInt32Field("data2");
			sGLMgr.addItemNum(pChr,ItemModel_Coins,coins_num);
			sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Task, ItemModel_Coins, en_UNT_Add, coins_num, model_id);
			// 更新任务状态
			if(sProtocolsMgr.CreateCommonSingleJsonMissionPacket(&packet,modelPtr->getHandle(),
								(*iterVal)["s"].asUInt(),(*iterVal)["n"].asUInt(),(*iterVal)["n"].asUInt()))
				sGLMgr.SendProtocolsToChr(pChr,&packet);
		}
	}
	
	if(!bNeedWriting)
		return false;
	
	Json::FastWriter w;
	pMission->setStringField("require", w.write(val));
	pMission->SaveDB();
	return true;
}

//======================================================================================
bool GameLogicManager::BuildCommonJsonEffort(CharPtr & pChr,std::list<ResourcePtr> effortModels, const uint32 & effort_modelid)
{
	uint32 model_id = effort_modelid;
	if(model_id == 0)
		model_id = sXmlDataMgr.GetConfXMLValue("COMMON_JSONEFFECT_MODELID");
	
	if(pChr.isNull() || !model_id || effortModels.empty())
		return false;
	
	// 找不到该任务模式
	EffectModelPtr efModel = sEffectModelMgr.load(model_id);
	if(efModel.isNull())
		return false;
	
	// 创建任务的玩家不在线
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	std::list<EffectPtr> myEffects;
	pChr->getEffectsList(&myEffects);
	
	EffectPtr pEffect;
	for (std::list<EffectPtr>::iterator it=myEffects.begin(); it!=myEffects.end(); it++)
	{
		if ((*it)->model->getSerial() == model_id)
		{// 获得指定任务
			pEffect = *it;
		}
		else
		{// 清除原来的任务
			(*it)->Destroy();
		}
	}
	
	if (!pEffect.isNull())
	{
		return false;
	}
	else
	{// 没找到成就，创建
		Resource* pNewEffect = sEffectMgr.newDumyEffect();
		pNewEffect->setUInt32Field("effect_model_id", model_id);
		pNewEffect->setUInt32Field("status", Effect::EffectStatusProcess);
		pNewEffect->setUInt32Field("owner_id", pChr->getHandle());
		pNewEffect->setUInt32Field("owner_type", pChr->getTargetType());
		pEffect = sEffectMgr.loadEffectDatabase(pNewEffect);
		sEffectMgr.freeDumyEffect(pNewEffect);
	}
	
	uint32 index = 0;
	Json::Value val;
	std::list<ResourcePtr>::iterator iter,ei = effortModels.end();
	for(iter = effortModels.begin(); iter!=ei; ++iter)
	{
		uint32 effect_modelID = (*iter)->getHandle();
		
		Json::Value val2;
		val2["model_id"] = effect_modelID;								//成就ID
		val2["complate_count"] = 0;										//完成进度
		val2["need_count"] = (*iter)->getUInt32Field("effect1");		//需求次数
		val2["status"] = enCommonEffectStatus_Process;					//成就状态status
		val2["finish_time"] = 0;										//完成时间finishtime
		val2["icon_id"] = (*iter)->getUInt32Field("icon");				//图标ID
		val2["name"] = (*iter)->getStringField("name");					//成就名称
		val2["desc"] = (*iter)->getStringField("desc");					//成就描述
		val2["bounty_num"] = (*iter)->getUInt32Field("effect2");		//奖励铜钱
		
		val[index++] = val2;
	}
	
	Json::FastWriter w;
	pEffect->setStringField("info", w.write(val));
	pEffect->SaveDB();
	return true;
}

//======================================================================================
bool GameLogicManager::BuildCommonJsonEffort(CharPtr & pChr, std::vector<stSignleEffortInfo> effortModels, const uint32 & effort_modelid, const uint8 & isSameDate)
{
	if(pChr.isNull() || effortModels.empty())
		return false;
	
	uint32 model_id = effort_modelid;
	if(model_id == 0)
		model_id = sXmlDataMgr.GetConfXMLValue("COMMON_JSONEFFECT_MODELID");
	
	if(!model_id)
		return false;
	
	// 找不到该任务模式
	EffectModelPtr efModel = sEffectModelMgr.load(model_id);
	if(efModel.isNull())
		return false;
	
	// 创建任务的玩家不在线
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	std::list<EffectPtr> myEffects;
	pChr->getEffectsList(&myEffects);
	
	EffectPtr pEffect;
	for (std::list<EffectPtr>::iterator it=myEffects.begin(); it!=myEffects.end(); it++)
	{
		if ((*it)->model->getSerial() == model_id)
		{// 获得指定任务
			pEffect = *it;
		}
		else
		{// 清除原来的任务
			(*it)->Destroy();
		}
	}
	
	if (!pEffect.isNull())
	{
		if(isSameDate)
			return false;
		
		bool bDaily = false;
		
		// 重置每日成就
		Json::Value val;
		Json::Reader reader;
		reader.parse(pEffect->getStringField("info"), val);
		
		for (Json::Value::iterator iterVal=val.begin(); iterVal!=val.end(); ++iterVal)
		{
			if((*iterVal)["daily"].asUInt() != 0)
			{
				bDaily = true;
				break;
			}
		}
		
		if(!bDaily)
			return false;
	}
	else
	{// 没找到成就，创建
		Resource* pNewEffect = sEffectMgr.newDumyEffect();
		pNewEffect->setUInt32Field("effect_model_id", model_id);
		pNewEffect->setUInt32Field("status", Effect::EffectStatusProcess);
		pNewEffect->setUInt32Field("owner_id", pChr->getHandle());
		pNewEffect->setUInt32Field("owner_type", pChr->getTargetType());
		pEffect = sEffectMgr.loadEffectDatabase(pNewEffect);
		sEffectMgr.freeDumyEffect(pNewEffect);
	}
	
	// 初始成就列表数据
	uint32 index = 0;
	Json::Value val;
	std::vector<stSignleEffortInfo>::iterator iter,ei = effortModels.end();
	for(iter = effortModels.begin(); iter!=ei; ++iter)
	{
		Json::Value val2;
		val2["model_id"] = (*iter).model_id;							//成就ID
		val2["complate_count"] = 0;										//完成进度
		val2["need_count"] = (*iter).need_count;						//需求次数
		val2["status"] = enCommonEffectStatus_Process;					//成就状态status
		val2["finish_time"] = 0;										//完成时间finishtime
		val2["icon_id"] = (*iter).model_id;								//图标ID和ID相同
		val2["name"] = (*iter).name;									//成就名称
		val2["desc"] = (*iter).content;									//成就描述
		val2["daily"] = (*iter).daily;									//是否日常
		val2["type"] = (*iter).type;									//任务类型
		
		uint32 bounty_coins = 0;
		std::map<uint32, uint32>::iterator fit = (*iter).mapBounties.find(ItemModel_Coins);
		if(fit != (*iter).mapBounties.end())
			bounty_coins = fit->second;
		
		val2["bounty_num"] = bounty_coins;								//奖励铜钱
		
		val[index++] = val2;
	}
	
	Json::FastWriter w;
	pEffect->setStringField("info", w.write(val));
	pEffect->SaveDB();
	return true;
}

//======================================================================================
bool GameLogicManager::ReSetCommonJsonEffort(CharPtr & pChr)
{
	if(pChr.isNull())
		return false;
	
	std::list<EffectPtr> effectList;
	pChr->getEffectsList(&effectList);
	if(effectList.empty())
		return false;
	
	EffectPtr pEffect = *effectList.begin();
	
	Json::Value val;
	Json::Reader reader;
	if (!pEffect.isNull())
	{// 重置任务数据
		reader.parse(pEffect->getStringField("info"), val);
	}
	else
	{// 没找到任务
		return false;
	}
	
	for (Json::Value::iterator iterVal=val.begin(); iterVal!=val.end(); ++iterVal)
	{// 重置成就状态，完成次数
		(*iterVal)["status"] = enCommonMissionStatus_Process;
		(*iterVal)["complate_count"] = 0;	
		(*iterVal)["finish_time"] = 0;
	}
	
	Json::FastWriter w;
	pEffect->setStringField("info", w.write(val));
	pEffect->SaveDB();
	return true;
}


//======================================================================================
bool GameLogicManager::AddEffortFinishCount(CharPtr & pChr,const uint32 & effort_type,const uint32 & count)
{
	if(pChr.isNull() || !effort_type || !count)
		return false;
	Log.Notice("GameLogicManager::AddEffortFinishCount","effort_type[%u] count[%u] ", effort_type, count);
	uint32 pid = 0;
	uint32 agent_id = 0;
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(!pUser.isNull())
	{
		pid = pUser->getUInt32Field("platform_id");
		agent_id = pUser->getUInt32Field("reg_from");
	}
	
	std::list<EffectPtr> effectList;
	pChr->getEffectsList(&effectList);
	if(effectList.empty())
		return false;
	
	EffectPtr pEffect = *effectList.begin();
	
	Json::Value val;
	Json::Reader reader;
	if (!pEffect.isNull())
	{// 重置任务数据
		reader.parse(pEffect->getStringField("info"), val);
	}
	else
	{// 没找到任务
		return false;
	}
	
	bool bNeedWriting = false;
	WorldPacket packet;
	
	for (Json::Value::iterator iterVal=val.begin(); iterVal!=val.end(); ++iterVal)
	{
		uint32 effectModelID = (*iterVal)["model_id"].asUInt();
		
		EffectModelPtr modelPtr = sEffectModelMgr.load(effectModelID);
		if(modelPtr.isNull())
			continue;
		
		if((*iterVal)["type"].asUInt() != effort_type)
			continue;
		
		// 未在进行中
		if((*iterVal)["status"].asUInt() != enCommonEffectStatus_Process)
			continue;
		
		// 2，支持一个加钱到网关并发送邮件提示信息的指令
		uint32 target_gzid = modelPtr->getUInt32Field("effect9"); 
		if(target_gzid)
		{// 向指定分区发送完成成就
			Log.Notice("GameLogicManager::AddEffortFinishCount","modelPtr[%u] target_gzid[%u] ", modelPtr->getHandle(), target_gzid);
			Json::Value valData;
			valData["gz_id"] = target_gzid;	
			valData["pid"] = pid;
			valData["type"] = effort_type;
			valData["model_id"] = uint32(modelPtr->getHandle());
			valData["count"] = count;
			valData["agent_id"] = agent_id;
			
			String strResult = SendAddEffortFinishCountFromGateway(valData);
			Json::Value valRet;
			reader.parse(strResult, valRet);
			Log.Notice("GameLogicManager::AddEffortFinishCount","modelPtr[%u] target_gzid[%u] strResult[%s]", modelPtr->getHandle(), target_gzid, strResult.c_str());
			
			// 完成状态
			if(valRet.isMember("status"))
			{
				uint8 result = valRet["status"].asUInt();
				if(result == 1 && valRet.isMember("data"))
				{// 发送成就更新信息
					
					for (Json::Value::iterator iterV=valRet["data"].begin(); iterV!=valRet["data"].end(); ++iterV)
					{
						// 更新任务状态
						if(sProtocolsMgr.CreateCommonSingleJsonMissionPacket(&packet, (*iterV)["model_id"].asUInt(), (*iterV)["status"].asUInt(), 
																		(*iterV)["complate_count"].asUInt(),(*iterV)["need_count"].asUInt()))
							sGLMgr.SendProtocolsToChr(pChr, &packet);
					}
				}
				
			}
			
			return true;
		}
		
		uint32 complate_count = (*iterVal)["complate_count"].asUInt() + count;
		uint32 max_num = (*iterVal)["need_count"].asUInt();
		(*iterVal)["complate_count"] = complate_count;
		
		if(complate_count >= max_num)
		{// 任务完成，更新任务状态
			(*iterVal)["status"] = enCommonMissionStatus_Finish;
			(*iterVal)["complate_count"] = max_num;	
			(*iterVal)["finish_time"] = uint32(time(0));	
		}
		
		bNeedWriting = true;
		
		if(sProtocolsMgr.CreateCommonSingleJsonEffectPacket(&packet,modelPtr->getHandle(),
									(*iterVal)["status"].asUInt(),(*iterVal)["complate_count"].asUInt(),max_num))
			sGLMgr.SendProtocolsToChr(pChr,&packet);
	}
	
	if(bNeedWriting)
	{
		Json::FastWriter w;
		pEffect->setStringField("info", w.write(val));
		pEffect->SaveDB();
	}
	
	return true;
}

bool GameLogicManager::AddEffortFinishCountByGateway(String strParmars, String & strReturn)
{
	Json::Value valData;
	Json::Reader reader;
	
	reader.parse(strParmars, valData);
	if(valData.empty())
		return false;
	
	uint32 pid = valData["pid"].asUInt();
	uint32 gz_id = valData["gz_id"].asUInt();
	uint32 count = valData["count"].asUInt();
	uint32 effort_type = valData["type"].asUInt();
	uint32 model_id = valData["model_id"].asUInt();
	uint32 extra_data1 = 0;
	if(valData.isMember("extra_data1"))
		extra_data1 = extra_data1;
	
	Log.Debug("GameLogicManager::AddEffortFinishCountByGateway","pid[%u] gz_id[%u] count[%u] effort_type[%u] model_id[%u]", pid, gz_id, count, effort_type, model_id);
	
	std::list<UserPtr> lstUser;
	sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u and gz_id = %u", pid, gz_id);
	if(lstUser.empty())
		return false;
	
	UserPtr pUser = *lstUser.begin();
	if(pUser.isNull())
		return false;
	
	CharPtr pChr = sCharMgr.load(pUser->getUInt32Field("char_id"));
	if(pChr.isNull())
		return false;
	
	std::list<EffectPtr> effectList;
	pChr->getEffectsList(&effectList);
	if(effectList.empty())
		return false;
	
	EffectPtr pEffect = *effectList.begin();
	
	Json::Value val;
	if (!pEffect.isNull())
	{// 重置任务数据
		Json::Reader reader;
		reader.parse(pEffect->getStringField("info"), val);
	}
	else
	{// 没找到任务
		return false;
	}
	
	bool bNeedWriting = false;
	WorldPacket packet;
	
	uint8 index = 0;
	Json::Value valRet;
	for (Json::Value::iterator iterVal=val.begin(); iterVal!=val.end(); ++iterVal)
	{
		uint32 effectModelID = (*iterVal)["model_id"].asUInt();
		if(effectModelID && effectModelID != model_id)
			continue;
		
		if((*iterVal)["type"].asUInt() != effort_type)
			continue;
		
		// 未在进行中
		if((*iterVal)["status"].asUInt() != enCommonEffectStatus_Process)
			continue;
		
		if((*iterVal).isMember("extra_data1"))
		{
			if((*iterVal)["extra_data1"].asUInt() != extra_data1)
				continue;
		}
		
		uint32 complate_count = (*iterVal)["complate_count"].asUInt() + count;
		uint32 max_num = (*iterVal)["need_count"].asUInt();
		(*iterVal)["complate_count"] = complate_count;
		
		if(complate_count >= max_num)
		{
			// 任务完成，更新任务状态
			(*iterVal)["status"] = enCommonMissionStatus_Finish;
			(*iterVal)["complate_count"] = max_num;	
			(*iterVal)["finish_time"] = uint32(time(0));
		}
		
		Json::Value valEff;
		valEff["status"] = (*iterVal)["status"].asUInt();
		valEff["complate_count"] = (*iterVal)["complate_count"].asUInt();
		valEff["model_id"] = model_id;
		valEff["need_count"] = (*iterVal)["need_count"].asUInt();
		valEff["type"] = (*iterVal)["type"].asUInt();
		
		valRet[index++] = valEff;
		
		bNeedWriting = true;
	}
	
	if(bNeedWriting)
	{
		Json::FastWriter w;
		pEffect->setStringField("info", w.write(val));
		pEffect->SaveDB();
		
		strReturn = w.write(valRet);
		return true;
	}
	
	return false;
}

//======================================================================================
String GameLogicManager::SendAddEffortFinishCountFromGateway(Json::Value & val)
{
	uint32 target_gzid = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	String strHttpHost = GetTargetHttpHost(target_gzid, agent_id);
	if(strHttpHost == "")
		return 0;
	
	Json::FastWriter w;
	String strData = w.write(val);
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "operate_effort?";			// Url方法名（操作成就）
	strUrl += "op=1";						// 操作(1 增加成就计数 2 判断成就计数 3 设置成就计数)
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	
	Log.Notice("GameLogicManager::SendAddEffortFinishCountFromGateway","strUrl[%s]", strUrl.c_str());
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);
	Log.Notice("GameLogicManager::SendAddEffortFinishCountFromGateway","recv_result[%s]", recv_result.c_str());
	return recv_result;
}

//======================================================================================
bool GameLogicManager::HasEffortCompalateAtValue(CharPtr & pChr,const uint32 & effort_type,const uint32 & value)
{
	if(pChr.isNull() || !effort_type || !value)
		return false;
	
	uint32 pid = 0;
	uint32 agent_id = 0;
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(!pUser.isNull())
	{
		pid = pUser->getUInt32Field("platform_id");
		agent_id = pUser->getUInt32Field("reg_from");
	}
	
	std::list<EffectPtr> effectList;
	pChr->getEffectsList(&effectList);
	if(effectList.empty())
		return false;
	
	EffectPtr pEffect = *effectList.begin();
	
	Json::Value val;
	Json::Reader reader;
	if (!pEffect.isNull())
	{// 重置任务数据
		reader.parse(pEffect->getStringField("info"), val);
	}
	else
	{// 没找到任务
		return false;
	}
	
	bool bNeedWriting = false;
	WorldPacket packet;
	
	for (Json::Value::iterator iterVal=val.begin(); iterVal!=val.end(); ++iterVal)
	{
		uint32 effectModelID = (*iterVal)["model_id"].asUInt();
		EffectModelPtr modelPtr = sEffectModelMgr.load(effectModelID);
		if(modelPtr.isNull())
			continue;
		
		if(modelPtr->getUInt32Field("type") != effort_type)
			continue;
		
		// 未在进行中
		if((*iterVal)["status"].asUInt() != enCommonEffectStatus_Process)
			continue;
		
		// 2，支持一个加钱到网关并发送邮件提示信息的指令
		uint32 target_gzid = modelPtr->getUInt32Field("data9"); 
		if(target_gzid)
		{// 向指定分区发送完成成就
			Json::Value valData;
			valData["gz_id"] = target_gzid;	
			valData["pid"] = pid;
			valData["type"] = effort_type;
			valData["model_id"] = uint32(modelPtr->getHandle());
			valData["count"] = value;
			valData["agent_id"] = agent_id;
			
			String strResult = SendAddEffortFinishCountFromGateway(valData);
			Json::Value valRet;
			reader.parse(strResult, valRet);
			
			// 完成状态
			if(valRet.isMember("status"))
			{
				uint8 result = valRet["status"].asUInt();
				if(result == 1 && valRet.isMember("data"))
				{// 发送成就更新信息
					
					for (Json::Value::iterator iterV=valRet["data"].begin(); iterV!=valRet["data"].end(); ++iterV)
					{
						// 更新任务状态
						if(sProtocolsMgr.CreateCommonSingleJsonMissionPacket(&packet, (*iterV)["model_id"].asUInt(), (*iterV)["status"].asUInt(), 
																		(*iterV)["complate_count"].asUInt(),(*iterV)["need_count"].asUInt()))
							sGLMgr.SendProtocolsToChr(pChr, &packet);
					}
				}
				
			}
			
			return true;
		}
		
		uint32 max_num = modelPtr->getUInt32Field("effect1");
		if(value >= max_num)
		{
			// 任务完成，更新任务状态
			(*iterVal)["status"] = enCommonEffectStatus_Finish;
			(*iterVal)["complate_count"] = max_num;
			(*iterVal)["finish_time"] = uint32(time(0));
		}
		
		bNeedWriting = true;
		
		if(sProtocolsMgr.CreateCommonSingleJsonEffectPacket(&packet,modelPtr->getHandle(),
							(*iterVal)["status"].asUInt(),(*iterVal)["complate_count"].asUInt(),max_num))
			sGLMgr.SendProtocolsToChr(pChr,&packet);
	}
	
	if(bNeedWriting)
	{
		Json::FastWriter w;
		pEffect->setStringField("info", w.write(val));
		pEffect->SaveDB();
	}
	
	return true;
}

//======================================================================================
bool GameLogicManager::HasEffortCompalateAtValueByGateway(String strParmars, String & strReturn)
{
	Json::Value valData;
	Json::Reader reader;
	
	reader.parse(strParmars, valData);
	if(valData.empty())
		return false;
	
	uint32 pid = valData["pid"].asUInt();
	uint32 gz_id = valData["gz_id"].asUInt();
	uint32 value = valData["count"].asUInt();
	uint32 mission_type = valData["type"].asUInt();
	
	std::list<UserPtr> lstUser;
	sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u and gz_id = %u", pid, gz_id);
	if(lstUser.empty())
		return false;
	
	UserPtr pUser = *lstUser.begin();
	if(pUser.isNull())
		return false;
	
	CharPtr pChr = sCharMgr.load(pUser->getUInt32Field("char_id"));
	if(pChr.isNull())
		return false;
	
	std::list<EffectPtr> effectList;
	pChr->getEffectsList(&effectList);
	if(effectList.empty())
		return false;
	
	EffectPtr pEffect = *effectList.begin();
	
	Json::Value val;
	if (!pEffect.isNull())
	{// 重置任务数据
		Json::Reader reader;
		reader.parse(pEffect->getStringField("info"), val);
	}
	else
	{// 没找到任务
		return false;
	}
	
	bool bNeedWriting = false;
	WorldPacket packet;
	
	uint8 index = 0;
	Json::Value valRet;
	for (Json::Value::iterator iterVal=val.begin(); iterVal!=val.end(); ++iterVal)
	{
		uint32 effectModelID = (*iterVal)["model_id"].asUInt();
		EffectModelPtr modelPtr = sEffectModelMgr.load(effectModelID);
		if(modelPtr.isNull())
			continue;
		
		if(modelPtr->getUInt32Field("type") != mission_type)
			continue;
		
		// 未在进行中
		if((*iterVal)["status"].asUInt() != enCommonEffectStatus_Process)
			continue;
		
		uint32 max_num = modelPtr->getUInt32Field("effect1");
		if(value >= max_num)
		{
			// 任务完成，更新任务状态
			(*iterVal)["status"] = enCommonEffectStatus_Finish;
			(*iterVal)["complate_count"] = max_num;
			(*iterVal)["finish_time"] = uint32(time(0));
		}
		
		Json::Value valEff;
		valEff["status"] = (*iterVal)["status"].asUInt();
		valEff["complate_count"] = (*iterVal)["complate_count"].asUInt();
		valEff["model_id"] = uint32(modelPtr->getHandle());
		valEff["need_count"] = (*iterVal)["need_count"].asUInt();
		
		valRet[index++] = valEff;
		
		bNeedWriting = true;
	}
	
	if(bNeedWriting)
	{
		Json::FastWriter w;
		pEffect->setStringField("info", w.write(val));
		pEffect->SaveDB();
		
		strReturn = w.write(valRet);
		return true;
	}
	
	return false;
}

String GameLogicManager::SendHasEffortCompalateAtValueFromGateway(Json::Value & val)
{
	uint32 target_gzid = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	String strHttpHost = GetTargetHttpHost(target_gzid, agent_id);
	if(strHttpHost == "")
		return 0;
	
	Json::FastWriter w;
	String strData = w.write(val);
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "operate_effort?";			// Url方法名（操作成就）
	strUrl += "op=2";						// 操作(1 增加成就计数 2 判断成就计数 3 设置成就计数)
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "2";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);
	// 调用url
	return recv_result;
}

//======================================================================================
bool GameLogicManager::SetEffortCompalateAtValue(CharPtr & pChr,const uint32 & effort_type,const uint32 & count)
{
	if(pChr.isNull() || !effort_type || !count)
		return false;
	
	uint32 pid = 0;
	uint32 agent_id = 0;
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(!pUser.isNull())
	{
		pid = pUser->getUInt32Field("platform_id");
		agent_id = pUser->getUInt32Field("reg_from");
	}
	
	std::list<EffectPtr> effectList;
	pChr->getEffectsList(&effectList);
	if(effectList.empty())
		return false;
	
	EffectPtr pEffect = *effectList.begin();
	
	Json::Value val;
	Json::Reader reader;
	if (!pEffect.isNull())
	{// 重置任务数据
		reader.parse(pEffect->getStringField("info"), val);
	}
	else
	{// 没找到任务
		return false;
	}
	
	bool bNeedWriting = false;
	WorldPacket packet;
	
	for (Json::Value::iterator iterVal=val.begin(); iterVal!=val.end(); ++iterVal)
	{
		uint32 effectModelID = (*iterVal)["model_id"].asUInt();
		EffectModelPtr modelPtr = sEffectModelMgr.load(effectModelID);
		if(modelPtr.isNull())
			continue;
		
		if(modelPtr->getUInt32Field("type") != effort_type)
			continue;
		
		// 未在进行中
		if((*iterVal)["status"].asUInt() != enCommonEffectStatus_Process)
			continue;
		
		// 2，支持一个加钱到网关并发送邮件提示信息的指令
		uint32 target_gzid = modelPtr->getUInt32Field("data9"); 
		if(target_gzid)
		{// 向指定分区发送完成成就
			Json::Value valData;
			valData["gz_id"] = target_gzid;	
			valData["pid"] = pid;
			valData["type"] = effort_type;
			valData["model_id"] = uint32(modelPtr->getHandle());
			valData["count"] = count;
			valData["agent_id"] = agent_id;
			
			String strResult = SendAddEffortFinishCountFromGateway(valData);
			Json::Value valRet;
			reader.parse(strResult, valRet);
			
			// 完成状态
			if(valRet.isMember("status"))
			{
				uint8 result = valRet["status"].asUInt();
				if(result == 1 && valRet.isMember("data"))
				{// 发送成就更新信息
					
					for (Json::Value::iterator iterV=valRet["data"].begin(); iterV!=valRet["data"].end(); ++iterV)
					{
						// 更新任务状态
						if(sProtocolsMgr.CreateCommonSingleJsonMissionPacket(&packet, (*iterV)["model_id"].asUInt(), (*iterV)["status"].asUInt(), 
																		(*iterV)["complate_count"].asUInt(),(*iterV)["need_count"].asUInt()))
							sGLMgr.SendProtocolsToChr(pChr, &packet);
					}
				}
				
			}
			
			return true;
		}
		
		uint32 max_num = modelPtr->getUInt32Field("effect1");
		(*iterVal)["complate_count"] = count;
		
		if(count >= max_num)
		{
			// 任务完成，更新任务状态
			(*iterVal)["status"] = enCommonMissionStatus_Finish;
			(*iterVal)["complate_count"] = max_num;
			(*iterVal)["finish_time"] = uint32(time(0));
		}
		
		bNeedWriting = true;
		
		if(sProtocolsMgr.CreateCommonSingleJsonEffectPacket(&packet,modelPtr->getHandle(),
									(*iterVal)["status"].asUInt(),(*iterVal)["complate_count"].asUInt(),max_num))
			sGLMgr.SendProtocolsToChr(pChr,&packet);
	}
	
	if(bNeedWriting)
	{
		Json::FastWriter w;
		pEffect->setStringField("info", w.write(val));
		pEffect->SaveDB();
	}
	
	return true;
}

//======================================================================================
bool GameLogicManager::SetEffortCompalateAtValueByGateway(String strParmars, String & strReturn)
{
	Json::Value valData;
	Json::Reader reader;
	
	reader.parse(strParmars, valData);
	if(valData.empty())
		return false;
	
	uint32 pid = valData["pid"].asUInt();
	uint32 gz_id = valData["gz_id"].asUInt();
	uint32 count = valData["count"].asUInt();
	uint32 effort_type = valData["type"].asUInt();
	
	std::list<UserPtr> lstUser;
	sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u and gz_id = %u", pid, gz_id);
	if(lstUser.empty())
		return false;
	
	UserPtr pUser = *lstUser.begin();
	if(pUser.isNull())
		return false;
	
	CharPtr pChr = sCharMgr.load(pUser->getUInt32Field("char_id"));
	if(pChr.isNull())
		return false;
	
	std::list<EffectPtr> effectList;
	pChr->getEffectsList(&effectList);
	if(effectList.empty())
		return false;
	
	EffectPtr pEffect = *effectList.begin();
	
	Json::Value val;
	if (!pEffect.isNull())
	{// 重置任务数据
		Json::Reader reader;
		reader.parse(pEffect->getStringField("info"), val);
	}
	else
	{// 没找到任务
		return false;
	}
	
	bool bNeedWriting = false;
	WorldPacket packet;
	
	uint8 index = 0;
	Json::Value valRet;
	for (Json::Value::iterator iterVal=val.begin(); iterVal!=val.end(); ++iterVal)
	{
		uint32 effectModelID = (*iterVal)["model_id"].asUInt();
		EffectModelPtr modelPtr = sEffectModelMgr.load(effectModelID);
		if(modelPtr.isNull())
			continue;
		
		if(modelPtr->getUInt32Field("type") != effort_type)
			continue;
		
		// 未在进行中
		if((*iterVal)["status"].asUInt() != enCommonEffectStatus_Process)
			continue;
		
		uint32 max_num = (*iterVal)["need_count"].asUInt();
		(*iterVal)["complate_count"] = count;
		
		if(count >= max_num)
		{
			// 任务完成，更新任务状态
			(*iterVal)["status"] = enCommonMissionStatus_Finish;
			(*iterVal)["complate_count"] = max_num;
			(*iterVal)["finish_time"] = uint32(time(0));
		}
		
		Json::Value valEff;
		valEff["status"] = (*iterVal)["status"].asUInt();
		valEff["complate_count"] = (*iterVal)["complate_count"].asUInt();
		valEff["model_id"] = uint32(modelPtr->getHandle());
		valEff["need_count"] = (*iterVal)["need_count"].asUInt();
		
		valRet[index++] = valEff;
		
		bNeedWriting = true;
	}
	
	if(bNeedWriting)
	{
		Json::FastWriter w;
		pEffect->setStringField("info", w.write(val));
		pEffect->SaveDB();
		
		strReturn = w.write(valRet);
		return true;
	}
	
	return false;
}

String GameLogicManager::SendSetEffortCompalateAtValueFromGateway(Json::Value & val)
{
	uint32 target_gzid = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	String strHttpHost = GetTargetHttpHost(target_gzid, agent_id);
	if(strHttpHost == "")
		return 0;
	
	Json::FastWriter w;
	String strData = w.write(val);
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "operate_effort?";			// Url方法名（操作成就）
	strUrl += "op=3";						// 操作(1 增加成就计数 2 判断成就计数 3 设置成就计数)
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "3";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);
	// 调用url
	return recv_result;
}

//======================================================================================
bool GameLogicManager::GetJsonEffortBounty(CharPtr & pChr,const uint32 & model_id)
{
	if(pChr.isNull() || !model_id)
		return false;
	
	std::list<EffectPtr> effectList;
	pChr->getEffectsList(&effectList);
	
	if(effectList.empty())
		return false;
	
	EffectPtr pEffect = *effectList.begin();
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(pEffect->getStringField("info"), val);
	
	bool bNeedWriting = false;
	WorldPacket packet;
	
	for (Json::Value::iterator iterVal=val.begin(); iterVal!=val.end(); ++iterVal)
	{
		uint32 effectModelID = (*iterVal)["model_id"].asUInt();
		if(effectModelID != model_id)
			continue;
		
		// 未达到完成状态的
		if((*iterVal)["status"].asUInt() != enCommonEffectStatus_Finish)
			continue;
		
		bNeedWriting = true;
		
		// 任务完成，更新任务状态为领取
		(*iterVal)["status"] = enCommonEffectStatus_GetBounty;
		
		// 发放任务奖励
		uint32 coins_num = (*iterVal)["bounty_num"].asUInt();
		if (coins_num)
		{
			sGLMgr.addItemNum(pChr, ItemModel_Coins, coins_num);
			sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Effect, ItemModel_Coins, en_UNT_Add, coins_num, effectModelID);
		}
		
		Log.Debug("GameLogicManager::GetJsonEffortBounty","model_id[%u] coins_num[%u]", effectModelID, coins_num);
		// 更新任务状态
		if(sProtocolsMgr.CreateCommonSingleJsonEffectPacket(&packet, effectModelID,
							(*iterVal)["status"].asUInt(),(*iterVal)["complate_count"].asUInt(),(*iterVal)["complate_count"].asUInt()))
			sGLMgr.SendProtocolsToChr(pChr,&packet);
	}
	
	if(!bNeedWriting)
		return false;
	
	Json::FastWriter w;
	pEffect->setStringField("info", w.write(val));
	pEffect->SaveDB();
	return true;
}

//====================================================================
uint32 GameLogicManager::GetJsonEffortComplateNumber(CharPtr & pChr)
{
	if(pChr.isNull())
		return 0;
	
	std::list<EffectPtr> effectList;
	pChr->getEffectsList(&effectList);
	
	if(effectList.empty())
		return false;
	
	uint32 complate_num = 0;
	EffectPtr pEffect = *effectList.begin();
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(pEffect->getStringField("info"), val);
	
	for (Json::Value::iterator iterVal=val.begin(); iterVal!=val.end(); ++iterVal)
	{
		// 未达到完成状态的
		if((*iterVal)["status"].asUInt() != enCommonEffectStatus_Finish)
			continue;
		
		++complate_num;
	}
	
	return complate_num;
}

//====================================================================
void GameLogicManager::UpdateCommonPlayerQueueTop(bool bForceUpdate)
{
	std::map<uint32,stOrderInfo> mapOrder = sXmlDataMgr.GetCommonOrderMap();
	if(mapOrder.empty())
		return ;
	
	uint32 time_now = time(0);
	m_bByGzid = (bool)sXmlDataMgr.GetConfXMLValue("IS_BY_GZID");
	if (m_bByGzid)
	{
		std::vector<uint32> vecGzIds = sXmlDataMgr.GetGameIDVector();
		for (int i = 0; i < (int)vecGzIds.size(); ++i)
		{
			std::map<uint32,stOrderInfo>::iterator iter,ei = mapOrder.end();
			for (iter = mapOrder.begin(); iter!=ei; ++iter)
			{
				std::map< uint32, std::map<uint32, uint32> >::iterator fitGz = m_mapOrderUpdateTimer.find(iter->first);
				if(fitGz == m_mapOrderUpdateTimer.end())
				{
					uint32 update_timer = time_now;
					if(iter->second.update_mode == 2)
					{// 天更新
						update_timer = sTools.FormatDataCeil(time_now);
					}
					else if(iter->second.update_mode == 3)
					{// 周更新
						update_timer = sTools.GetMondayTime(time_now);
					}
					
					// Log.Debug("GameLogicManager::UpdateCommonPlayerQueueTop","order_type[%u] gz_id[%u] update_timer[%u] time_now[%u] 111", iter->first, vecGzIds[i], update_timer, time_now);
					std::map<uint32, uint32> mapOrderUpdate;
					mapOrderUpdate.insert(std::make_pair(iter->first, update_timer));
					
					m_mapOrderUpdateTimer.insert(std::make_pair(vecGzIds[i], mapOrderUpdate));
				}
				else
				{
					std::map<uint32, uint32>::iterator fit = fitGz->second.find(iter->first);
					if(fit == fitGz->second.end())
					{// 设置更新时间
						uint32 update_timer = time_now;
						if(iter->second.update_mode == 2)
						{// 天更新
							update_timer = sTools.FormatDataCeil(time_now);
						}
						else if(iter->second.update_mode == 3)
						{// 周更新
							update_timer = sTools.GetMondayTime(time_now);
						}
						
						// Log.Debug("GameLogicManager::UpdateCommonPlayerQueueTop","order_type[%u] gz_id[%u] update_timer[%u] time_now[%u] 111", iter->first, vecGzIds[i], update_timer, time_now);
						fitGz->second.insert(std::make_pair(iter->first, update_timer));
					}
					else
					{
						// Log.Debug("GameLogicManager::UpdateCommonPlayerQueueTop","order_type[%u] gz_id[%u] update_timer[%u] time_now[%u] 222", iter->first, vecGzIds[i], fit->second, time_now);
						if(time_now < fit->second && !bForceUpdate)
						{// 更新时间未到
							continue;
						}
						
						if(iter->second.update_mode == 2)
						{// 天更新
							fit->second = sTools.FormatDataCeil(time_now);
						}
						else if(iter->second.update_mode == 3)
						{// 周更新
							fit->second = sTools.GetMondayTime(time_now);
						}
						
						// Log.Debug("GameLogicManager::UpdateCommonPlayerQueueTop","order_type[%u] gz_id[%u] update_timer[%u] time_now[%u] 333", iter->first, vecGzIds[i], fit->second, time_now);

					}
				}
				
				/* std::map<uint32, uint32>::iterator fit = m_mapOrderUpdateTimer.find(iter->first);
				if(fit == m_mapOrderUpdateTimer.end())
				{// 设置更新时间
					uint32 update_timer = time_now;
					if(iter->second.update_mode == 2)
					{// 天更新
						update_timer = sTools.FormatDataCeil(time_now);
					}
					else if(iter->second.update_mode == 3)
					{// 周更新
						update_timer = sTools.GetMondayTime(time_now);
					}
					
					Log.Debug("GameLogicManager::UpdateCommonPlayerQueueTop","order_type[%u] gz_id[%u] update_timer[%u] time_now[%u] 111", iter->first, vecGzIds[i], update_timer, time_now);
					m_mapOrderUpdateTimer.insert(std::make_pair(iter->first, update_timer));
				}
				else
				{
					Log.Debug("GameLogicManager::UpdateCommonPlayerQueueTop","order_type[%u] gz_id[%u] update_timer[%u] time_now[%u] 222", iter->first, vecGzIds[i], fit->second, time_now);
					if(time_now < fit->second)
					{// 更新时间未到
						continue;
					}
					
					if(iter->second.update_mode == 2)
					{// 天更新
						fit->second = sTools.FormatDataCeil(time_now);
					}
					else if(iter->second.update_mode == 3)
					{// 周更新
						fit->second = sTools.GetMondayTime(time_now);
					}
					
					Log.Debug("GameLogicManager::UpdateCommonPlayerQueueTop","order_type[%u] gz_id[%u] update_timer[%u] time_now[%u] 333", iter->first, vecGzIds[i], fit->second, time_now);
				} */
				
				bool bResetData = false;
				if(iter->second.last_resetTimer)
				{// 判断时间是否需要重置
					if(iter->second.reset_mode == 2)
					{// 天更新
						if(time_now > iter->second.last_resetTimer && time_now - iter->second.last_resetTimer >= 86400 * iter->second.reset_data)
							bResetData = true;
					}
					else if(iter->second.reset_mode == 3)
					{// 周更新
						if(time_now > iter->second.last_resetTimer && time_now - iter->second.last_resetTimer >= 86400 * iter->second.reset_data * 7)
							bResetData = true;
					}
				}
				else
				{// 修改重置排行时间
					bResetData = true;
				}
				
				if(bResetData && iter->second.reset_mode)
				{// 重置时间到并且有重置模式的
					sXmlDataMgr.SetCommonOrderResetTimer(iter->first, time_now);
					CharacterDatabase.WaitExecute("update `game_chars` set `%s` = 0 where `gz_id` = %u", iter->second.orderValu_key.c_str(), vecGzIds[i]);
					Log.Debug("GameLogicManager::UpdateCommonPlayerQueueTop","order_type[%u] gz_id[%u] reset_mode[%u]", iter->first, vecGzIds[i], iter->second.reset_mode);
				}
				
				ThreadPool.ExecuteTask(new LoadPlayerCommonTop(iter->first, vecGzIds[i]));
			}
		}
	}
	else
	{
		std::map<uint32,stOrderInfo>::iterator iter,ei = mapOrder.end();
		for (iter = mapOrder.begin(); iter!=ei; ++iter)
		{
			std::map< uint32, std::map<uint32, uint32> >::iterator fitGz = m_mapOrderUpdateTimer.find(0);
			if(fitGz == m_mapOrderUpdateTimer.end())
			{
				uint32 update_timer = time_now;
				if(iter->second.update_mode == 2)
				{// 天更新
					update_timer = sTools.FormatDataCeil(time_now);
				}
				else if(iter->second.update_mode == 3)
				{// 周更新
					update_timer = sTools.GetMondayTime(time_now);
				}
				
				Log.Debug("GameLogicManager::UpdateCommonPlayerQueueTop","order_type[%u] update_timer[%u] time_now[%u] 444", iter->first, update_timer, time_now);
				std::map<uint32, uint32> mapOrderUpdate;
				mapOrderUpdate.insert(std::make_pair(iter->first, update_timer));
				
				m_mapOrderUpdateTimer.insert(std::make_pair(0, mapOrderUpdate));
			}
			else
			{
				std::map<uint32, uint32>::iterator fit = fitGz->second.find(iter->first);
				if(fit == fitGz->second.end())
				{// 设置更新时间
					uint32 update_timer = time_now;
					if(iter->second.update_mode == 2)
					{// 天更新
						update_timer = sTools.FormatDataCeil(time_now);
					}
					else if(iter->second.update_mode == 3)
					{// 周更新
						update_timer = sTools.GetMondayTime(time_now);
					}
					
					fitGz->second.insert(std::make_pair(iter->first, update_timer));
				}
				else
				{
					if(time_now > fit->second)
					{// 更新时间未到
						continue;
					}
					
					if(iter->second.update_mode == 2)
					{// 天更新
						fit->second = sTools.FormatDataCeil(time_now);
					}
					else if(iter->second.update_mode == 3)
					{// 周更新
						fit->second = sTools.GetMondayTime(time_now);
					}
				}
				
				ThreadPool.ExecuteTask(new LoadPlayerCommonTop(iter->first, 0));
			}
		}
	}
}

//====================================================================
void GameLogicManager::UpdateCommonPlayerTop(const uint32 gzId, const uint32 topType, std::list<stCommonQueueTop> &lstQT)
{
WGS_ORDER_LOCK
	std::map<uint32, std::map<uint32, CommonTopList> >::iterator iter = m_mapTopQueues.find(gzId);
	if (iter == m_mapTopQueues.end())
	{
		std::map<uint32, CommonTopList> myTop;
		myTop.insert(std::make_pair(topType, lstQT));
		m_mapTopQueues.insert(std::make_pair(gzId, myTop));
	}
	else
	{
		std::map<uint32, CommonTopList>::iterator iterTop = iter->second.find(topType);
		if (iterTop == iter->second.end())
		{
			iter->second.insert(std::make_pair(topType, lstQT));
		}
		else
		{
			uint32 num1 = 0;
			std::list<stCommonQueueTop>::iterator iter1 = lstQT.begin();
			for (; iter1 != lstQT.end(); ++iter1)
			{
				++num1;
				uint32 num2 = 0;
				std::list<stCommonQueueTop>::iterator iter2 = iterTop->second.begin();
				for (; iter2 != iterTop->second.end(); ++iter2)
				{
					++num2;
					if ((*iter2).id == (*iter1).id)
					{
						if (num1 < num2)
						{
							(*iter1).trend = 0;
						}
						else if (num1 == num2)
						{
							(*iter1).trend = 1;
						}
						else
						{
							(*iter1).trend = 2;
						}
						num2 = 0;
						break;
					}
				}
				if (num2 > 0)
				{
					(*iter1).trend = 2;
				}
			}
			iterTop->second.clear();
			iterTop->second = lstQT;
		}
	}
}

//====================================================================
void GameLogicManager::GetCommonTopQueue(CharPtr & pChr,const uint32 gzId,const uint32 topType)
{
	if (pChr.isNull())
		return;
	
	CommonTopList lstTop;
	{
		WGS_ORDER_LOCK
		std::map<uint32, std::map<uint32, CommonTopList> >::iterator iter;
		if (m_bByGzid)
			iter = m_mapTopQueues.find(gzId);
		else
			iter = m_mapTopQueues.begin();
		
		if (iter != m_mapTopQueues.end())
		{
			std::map<uint32, CommonTopList>::iterator iterTop = iter->second.find(topType);
			if (iterTop != iter->second.end())
			{
				lstTop = iterTop->second;
			}
		}
	}
	
	Log.Debug("GameLogicManager::GetCommonTopQueue","gzId[%u] topType[%u] lstTop[%u]",gzId,topType,lstTop.size());
	WorldPacket packet;
	if (sProtocolsMgr.CreateCommonTopQueuePacket(&packet, topType, lstTop))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
}

//====================================================================
void GameLogicManager::GetCommonTopQueueNew(CharPtr & pChr,const uint32 gzId,const uint32 topType, const uint8 & offset, const uint8 & num)
{
	if (pChr.isNull())
		return;
	
	uint32 agent_id = 0;
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(!pUser.isNull())
		agent_id = pUser->getUInt32Field("reg_from");
	
	CommonTopList lstTop;
	{
		WGS_ORDER_LOCK
		std::map<uint32, std::map<uint32, CommonTopList> >::iterator iter;
		if (m_bByGzid)
			iter = m_mapTopQueues.find(gzId);
		else
			iter = m_mapTopQueues.begin();
		
		if (iter != m_mapTopQueues.end())
		{
			std::map<uint32, CommonTopList>::iterator iterTop = iter->second.find(topType);
			if (iterTop != iter->second.end())
			{
				lstTop = iterTop->second;
			}
		}
	}
	
	
	
	uint8 isOpen = 0;
	char buf[256] = "";
	sprintf(buf, "OPEN_COMMON_ORDERNEW_DATASEND_%u", agent_id);
	
	String strConf = buf;
	
	Log.Debug("GameLogicManager::GetCommonTopQueueNew","gzId[%u] topType[%u] lstTop[%u] strConf[%s]",gzId, topType, lstTop.size(), strConf.c_str());
	
	if(sXmlDataMgr.IsConfXmlValueExist(strConf))
	{// 取到代理配置
		isOpen = sXmlDataMgr.GetConfXMLValue(strConf);
	}
	else
	{//未取到代理配置
		isOpen = sXmlDataMgr.GetConfXMLValue("OPEN_COMMON_ORDERNEW_DATASEND_0");
	}
	
	if(!isOpen)
		lstTop.clear();	// 通过配置控制是否开启排行数据的发送
	
	WorldPacket packet;
	if (sProtocolsMgr.CreateCommonTopQueueNewPacket(&packet, topType, lstTop, offset, num))
		sGLMgr.SendProtocolsToChr(pChr,&packet);
}

/*******************************每日输赢限额相关******************************/
// 增加每日输赢
void GameLogicManager::AddDayWinLoseLimitCoins(CharPtr & pChr,int winLose)
{
	if(pChr.isNull() || pChr->isNPC())
		return ;
	
	AICreatureBaseInterface * pChrAiInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(!pChrAiInfe)
		return ;
	
	pChrAiInfe->AddIntXMLValue("DAY_WINLOSE_LIMIT",winLose);
}

// 减少每日输赢
void GameLogicManager::ReduceDayWinLoseLimitCoins(CharPtr & pChr,int winLose)
{
	if(pChr.isNull() || pChr->isNPC())
		return ;
	
	AICreatureBaseInterface * pChrAiInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(!pChrAiInfe)
		return ;
	
	pChrAiInfe->ReduceIntXMLValue("DAY_WINLOSE_LIMIT",winLose);
}

// 重置每日输赢总额
void GameLogicManager::ReSetDayWinLoseLimitCoins(CharPtr & pChr)
{
	if(pChr.isNull())
		return ;
	
	AICreatureBaseInterface * pChrAiInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(!pChrAiInfe)
		return ;
	
	pChrAiInfe->SetIntXMLData("DAY_WINLOSE_LIMIT",0);
}

// 是否达到输赢限额
uint8 GameLogicManager::IsReachDayWinLoseLimitCoins(CharPtr & pChr)
{
	if(pChr.isNull() || pChr->isNPC())
		return 0;
	
	int win_limit = sXmlDataMgr.GetConfXMLValue("DAY_WIN_LIMIT");
	int lose_limit = sXmlDataMgr.GetConfXMLValue("DAY_LOSE_LIMIT");
	lose_limit *= (-1);
	
	if(!win_limit && !lose_limit)
		return 0;
	
	AICreatureBaseInterface * pChrAiInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(!pChrAiInfe)
		return 0;
	
	int winLose_LimitCoins = pChrAiInfe->GetIntXMLData("DAY_WINLOSE_LIMIT");
	if(win_limit && winLose_LimitCoins >= win_limit)
		return 1;
	
	if(lose_limit && winLose_LimitCoins <= lose_limit)
		return 2;
	
	return 0;
}

/*******************************每日输赢限额相关******************************/
ChannelPtr GameLogicManager::CreateCenterChannel(stPlayerCreateCenterBattle stPCB)
{
	ChannelPtr pChannel;
	Log.Debug("GameLogicManager::CreateCenterChannel","game_id[%u] mode[%u] 111", stPCB.game_id, stPCB.mode);
	// 获取
	stCenterBattleMode stCBM = sXmlDataMgr.GetCenterBattleModeByGameid(stPCB.game_id, stPCB.mode);
	if(stCBM.town_id == 0)
		return pChannel;
	Log.Debug("GameLogicManager::CreateCenterChannel","town_id[%u] 222", stCBM.town_id);
	TownPtr pTown = sTownMgr.getByHandle(stCBM.town_id);
	if (pTown.isNull())
		return pChannel;
	
	Resource * pChn = sChannelMgr.newDumyChannel();
	
	pChn->setUInt32Field("ai", pTown->getUInt32Field("ai"));
	pChn->setUInt32Field("town_id", pTown->getHandle());
	
	Vector3 pos = sRegionMgr.getWorldRondomPosition();
	pChn->setFloatField("x", pos.x);
	pChn->setFloatField("y", pos.y);
	pChn->setFloatField("z", pos.z);
	
	uint32 check_count;
	// String strCode = "888888";
	String strCode = "";
	uint8 code_num = sXmlDataMgr.GetConfXMLValue("CENTERBATTLE_CODE_COUNT");
	while(1)
	{// 随机验证码，最多6位
		if(check_count == 20)
		{
			if(code_num < 6)
				code_num++;
			
			check_count = 0;
		}
		
		switch(code_num)
		{
		case 4:
			strCode = StringConverter::toString(RandomUInt(1000,9999));
			break;
		case 5:
			strCode = StringConverter::toString(RandomUInt(10000,99999));
			break;
		default:
			strCode = StringConverter::toString(RandomUInt(100000,999999));
			break;
		}
		
		uint32 count = sChannelMgr.getDBCount("status <> 255 and winner = '%s' ",strCode.c_str());
		if(!count)
			break;
		
		++check_count;
	}
	
	pChn->setStringField("winner", strCode.c_str());	// 进入验证码
	pChn->setUInt32Field("type", 100);					// 组局类型65
	pChn->setUInt32Field("status", 1);					// 牌桌状态
	pChn->setUInt32Field("server_id", sRegionMgr.getServerID());				
	pChn->setUInt32Field("world_server_id", sRegionMgr.getServerID());			
	pChn->setUInt32Field("create_time", time(0));		// 创建时间
	
	// info字段以json格式写入牌桌对应参数
	Json::Value val;
	
	val["fz_pid"] = stPCB.pid;					// 房主PID
	val["cb_id"] = stPCB.cb_id;					// 组局ID
	val["base_coins"] = stPCB.base_coins;		// 底分
	val["fan_coins"] = stPCB.fan_coins;			// 翻分
	val["coins_model"] = stPCB.coins_model;		// 游戏用货币类型
	val["init_coins"] = stPCB.init_coins;		// 进入房间限制（初始带入货币数量）
	val["think_time"] = stPCB.think_time;		// 考虑时间
	val["timeout"] = stPCB.timeout;				// 超时时间
	val["battle_name"] = stPCB.battle_name;		// 房间名称
	val["limit_loop"] = stPCB.limit_loop;		// 局数限制
	val["limit_time"] = stPCB.limit_time;		// 时间限制
	val["top_times"] = stPCB.top_times;			// 封顶翻数配置
	val["game_id"] = stPCB.game_id;				// 游戏ID
	val["gz_id"] = stPCB.gz_id;					// 游戏分区ID
	val["mode"] = stPCB.mode;					// 游戏模式
	
	Json::Value valExtra;
	Json::Reader reader;
	reader.parse(stPCB.extra_data, valExtra);
	
	if(valExtra.size())
	{
		for (Json::Value::iterator iterV=valExtra.begin(); iterV!=valExtra.end(); ++iterV)
		{// 游戏玩法json节点复制
			if((*iterV).isString())
				val["extra_data"][iterV.key().asString()] = (*iterV).asString();
			else
				val["extra_data"][iterV.key().asString()] = (*iterV).asUInt();
		}
	}
	
	
	Json::FastWriter w;
	Log.Debug("GameLogicManager::CreateCenterChannel","val[%s]", w.write(val).c_str());
	pChn->setStringField("info", w.write(val));				//组局数据相关配置
	
	pChannel = sChannelMgr.loadChannelDatabase(pChn);
	sChannelMgr.freeDumyChannel(pChn);
	
	return pChannel;
}

bool GameLogicManager::CheckHaveSameIpPlayers(std::vector<CharPtr> vChars)
{
	// 人数低于3人，不检测同IP的问题
	if(vChars.empty())
		return false;
	
	std::map<uint32, std::vector<CharPtr> > mapSameIPChars;
	bool bHaveSameIpPlayer = false;
	std::map<uint32, std::vector<CharPtr> > mapSameIp;
	
	// IP检测前3段相同即认为是同IP
	std::vector<CharPtr>::iterator iter, ei = vChars.end();
	for(iter = vChars.begin(); iter!=ei; ++iter)
	{
		CharPtr pChr = *iter;
		if(pChr.isNull())
			return false;
		
		WSSocketPtr socket = pChr->getSocket();
		if(socket.isNull())
			return false;
		
		uint32 numIp = socket->GetNumIP() >> 8;
		std::map<uint32, std::vector<CharPtr> >::iterator fit = mapSameIp.find(numIp);
		if(fit == mapSameIp.end())
		{
			std::vector<CharPtr> chars;
			chars.push_back(pChr);
			
			mapSameIp.insert(std::make_pair(numIp, chars));
		}
		else
		{
			fit->second.push_back(pChr);
			bHaveSameIpPlayer = true;
		}
	}
	
	if(bHaveSameIpPlayer)
	{
		std::map<uint32, std::vector<CharPtr> >::iterator itMap, eiMap = mapSameIp.end();
		for(itMap = mapSameIp.begin(); itMap!=eiMap; ++itMap)
		{
			if(itMap->second.size() > 1)
			{
				mapSameIPChars.insert(std::make_pair(itMap->first, itMap->second));
			}
		}
	}
	
	WorldPacket packet;
	sProtocolsMgr.CreateCenterBattleSameIpPlayersPacket(&packet, mapSameIPChars, sXmlDataMgr.GetConfXMLValue("CENTER_BATTLE_SAMEIP_WAITSTARTTIMER"));
	
	// 发送同IP玩家信息
	for(iter = vChars.begin(); iter!=vChars.end(); ++iter)
	{
		CharPtr pChr = *iter;
		if(pChr.isNull())
			return false;
		
		sGLMgr.SendProtocolsToChr(pChr, &packet);
	}
	
	return mapSameIPChars.size();
}

ChannelPtr GameLogicManager::CreateCenterChannel()
{
	ChannelPtr pChannel;

	TownPtr pTown = sTownMgr.getByHandle(sXmlDataMgr.GetConfXMLValue("CENTER_BATTLE_TOWN"));
	if (pTown.isNull())
	{
		Log.Debug("GameLogicManager::CreateCenterChannel","pTown is null");
		return pChannel;
	}
	
	Log.Debug("GameLogicManager::CreateCenterChannel","pTown[%u]", pTown->getHandle());
	
	Resource * pChn = sChannelMgr.newDumyChannel();
	
	pChn->setUInt32Field("ai", pTown->getUInt32Field("ai"));
	pChn->setUInt32Field("town_id", pTown->getHandle());
	
	Vector3 pos = sRegionMgr.getWorldRondomPosition();
	pChn->setFloatField("x", pos.x);	
	pChn->setFloatField("y", pos.y);	
	pChn->setFloatField("z", pos.z);
	
	uint32 game_id = sXmlDataMgr.GetConfXMLValue("MY_GAME_ID");
	
	String strCode = "";
	strCode = StringConverter::toString(game_id);
	
	pChn->setStringField("winner", strCode.c_str());	// 进入验证码
	pChn->setUInt32Field("type", 100);					// 组局类型65
	pChn->setUInt32Field("status", 1);					// 牌桌状态
	pChn->setUInt32Field("server_id", sRegionMgr.getServerID());				
	pChn->setUInt32Field("world_server_id", sRegionMgr.getServerID());			
	pChn->setUInt32Field("create_time", time(0));		// 创建时间
	
	// info字段以json格式写入牌桌对应参数
	Json::Value val;
	// uint32 uid = 3;
	// uint32 pid = 99;
	
	val["cb_id"] = 281;				//组局ID
	val["fz_uid"] = 376;			//房主UID
	val["fz_pid"] = 1461831909;		//房主PID
	val["base_coins"] = 100;		//底分
	val["fan_coins"] = 7;			//翻分
	val["coins_model"] = 1001;		//游戏用货币类型
	val["init_coins"] = 0;			//进入房间限制（初始带入货币数量）
	val["think_time"] = 10000;		//考虑时间
	val["timeout"] = 10000;			//超时时间
	val["battle_name"] = "测试001";	//房间名称
	val["limit_loop"] = 3;			//局数限制
	val["limit_time"] = 0;			//时间限制
	val["game_id"] = 0;				//游戏ID
	val["gz_id"] = 18;				//游戏分区ID
	val["top_times"] = 7;			//封顶翻数配置
	
	Json::FastWriter w;
	pChn->setStringField("info", w.write(val));				//组局数据相关配置
	
	pChannel = sChannelMgr.loadChannelDatabase(pChn);
	sChannelMgr.freeDumyChannel(pChn);
	return pChannel;
}

void GameLogicManager::DoSomethingBeforeExitGameServer(CharPtr & pChr)
{
	if(pChr.isNull())
		return ;
	
	// TODO
}

// 检测组局牌桌非正常结束
void GameLogicManager::CheckZujuChannelOver()
{
	// 取出组局游戏没有完成的游戏
	uint32 count = sChannelMgr.getDBCount("status <> 255 and type = %u", 100);
	if(count)
	{
		std::list<ResourcePtr> objs;
		sChannelMgr.getDBObjects(&objs ,0 ,count ,"status <> 255 and type = %u", 100);
		
		std::set<uint32> setClubRoomId;
		std::list<ResourcePtr>::iterator itChn,eiChn = objs.end();
		for(itChn = objs.begin(); itChn!=eiChn; ++itChn)
		{
			Json::Reader reader;
			Json::Value val;
			reader.parse((*itChn)->getStringField("info"), val);
			
			uint32 cb_id = 0;
			if(val.isMember("cb_id"))
			{// 组局ID
				cb_id = val["cb_id"].asUInt();
			}
			
			if(val.isMember("extra_data"))
			{
				Json::Value val2 = val["extra_data"];
				if(val2.isMember("club_room_id"))
				{// 俱乐部房间ID
					setClubRoomId.insert(val2["club_room_id"].asUInt());
				}
			}
			
			Log.Debug("CheckZujuChannelOver","channel[%u] cb_id[%u]", (*itChn)->getUInt32Field("cid"), cb_id);
			
			// 因为服务器重启导致组局结束都算作重新来
			sCenterBattleMgr.CenterBattleComplate(cb_id, enCenterBattleReturnGold_ServerRestart);
			// 处理牌桌结束时间
			sCenterBattleLogMgr.CountBattleLogUseTime(cb_id);
		}
		
		if(setClubRoomId.size())
		{// 删除还在运行的房间
			
		}
		
	}
}

bool GameLogicManager::SendItemToUser(CharPtr & pChr, const uint32 & recv_pid, const uint32 & model_id, const uint32 & num)
{
	if(pChr.isNull() || model_id == 0 || num == 0)
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint32 my_pid = pUser->getUInt32Field("platform_id");
	
	GameBank recvBank;
	uint8 result = 1;
	do
	{
		if(my_pid == recv_pid)
		{// 不能赠送给自己
			result = 2;
			break;
		}
		
		if (!sBankMgr.GetPublicData(recv_pid, &recvBank))
		{// 目标对象不存在
			result = 3;
			break;
		}
		
		uint32 haveItemNm = GetItemNum(pChr, model_id);
		if(haveItemNm < num)
		{// 道具数量不足
			result = 4;
			break;
		}
		
		if(haveItemNm < num + sXmlDataMgr.GetConfXMLValue("GIVE_DIAMAND_LINE"))
		{// 低于保底线，不能赠送
			result = 5;
			break;
		}
		
		if(!reduceItemNum(pChr, model_id, num))
		{// 扣钱失败，道具不足
			result = 4;
			break;
		}
		
	}while(0);
	
	// 发送操作结果
	WorldPacket packet;
	if(sProtocolsMgr.CreateGiveItemResultPacket(&packet, recv_pid, model_id, num, result))
		SendProtocolsToChr(pChr, &packet);
	
	if(result == 1)
	{
		// 发送邮件
		std::map<uint32,uint32> mapItems;
		mapItems.insert(std::make_pair(model_id, num));
		
		String szTitle = "";
		String szContent = "";
		char buf[256] = "";
		String recvNick = "";
		
		const MailModel * mailM = sXmlDataMgr.GetMailModel("SENDITEM_MAIL");
		if(mailM)
		{
			szTitle = mailM->szTitle;
			szContent = mailM->szContent;
			
			std::list<ResourcePtr> objs;
			sUserMgr.getDBObjects(&objs, 0, 1, " platform_id = %u ", recv_pid);
			
			if(objs.size())
				recvNick = (*objs.begin())->getStringField("nick");
			
			// 亲爱的%s：玩家【%s】赠送给您%s%u！
			sprintf(buf, szContent.c_str(), recvNick.c_str(), pChr->getCharName().c_str(), GetItemName(model_id).c_str(), num);
		}
		
		CreateMail(recv_pid, szTitle, buf, my_pid, en_ST_UserGiveItem, &mapItems);
		
		std::list<UserPtr> lstRecvUser;
		sUserMgr.getUserList(&lstRecvUser, 0, 1, "platform_id = %u", recv_pid);
		if (!lstRecvUser.empty())
		{
			UserPtr pRecvUser = lstRecvUser.front();
			if (!pRecvUser.isNull())
			{
				CharPtr pRecvChr = sCharMgr.getByHandle(pRecvUser->getUInt32Field("char_id"));
				if(!pRecvChr.isNull())
				{// 角色在线发送邮件未读数量
					if (sProtocolsMgr.CreateSendUnreadMailNumberPacket(&packet, pRecvUser))
						sGLMgr.SendProtocolsToChr(pRecvChr, &packet);
				}
			}
		}
		
		// 赠送日志
		UserGiveItemLog(pUser, recv_pid, recvNick, model_id, num, GetItemNum(pChr, model_id));
		// 获赠日志
		UserRecvItemLog(recv_pid, recvNick, pUser, model_id, num);
	}
	
	return true;
}

//道具赠送日志
bool GameLogicManager::UserGiveItemLog(UserPtr &pGiveUser, const uint32 & recv_pid, String recv_name, const uint32 & model_id, const uint32 & num, const uint32 & kucun)
{
	if(pGiveUser.isNull())
		return false;
	
	GameLog *pLog = sChannelMgr.newDumyCenterLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return false;
	}
	
	uint32 pid = pGiveUser->getUInt32Field("platform_id");
	
	pLog->status = 1;
	pLog->type = en_Operate_GiveItem;
	pLog->sub_type = 1;									// 赠送
	pLog->src_id= pid;									// 赠送方PID
	pLog->dest_id= recv_pid;							// 获赠方PID
	
	pLog->platform_id = pid;
	pLog->user_name = pGiveUser->getStringField("name");	// 用户Session
	pLog->user_nick = pGiveUser->getStringField("nick");	// 昵称
	pLog->user_ip = pGiveUser->getStringField("ip");		// IP地址
	pLog->user_addr = pGiveUser->getStringField("addr");	// 地址
	
	pLog->data1 = model_id;								// 宠物ID
	pLog->data2 = num;									// 操作数量
	pLog->data4 = kucun;								// 库存
	
	pLog->sdata1 = recv_name;							// 目标玩家昵称
	
	pLog->create_time = sTools.GetCurDateTime();
	sChannelMgr.addCenterLogDB(pLog);
	sChannelMgr.freeDumyCenterLog(pLog);
	Log.Debug("CenterHappyFarmManager::HappyFarmGiveLog","user[%u] pid[%u]", pGiveUser->getHandle(), pid);
	return true;
}

//宠物获赠日志
bool GameLogicManager::UserRecvItemLog(const uint32 &recv_pid, String &recv_name, UserPtr &pGiveUser, const uint32 & model_id, const uint32 & num)
{
	if(pGiveUser.isNull())
		return false;
	
	GameLog *pLog = sChannelMgr.newDumyCenterLog();
	if(NULL == pLog)
	{
		sChannelMgr.freeDumyLog(pLog);
		return false;
	}

	pLog->status = 1;
	pLog->type = en_Operate_GiveItem;
	pLog->sub_type = 2;										 // 获赠
	pLog->src_id= recv_pid;									 // 获赠方PID
	pLog->dest_id = pGiveUser->getUInt32Field("platform_id");// 赠送方PID
	
	pLog->platform_id = recv_pid;
	pLog->user_nick = recv_name;							// 昵称
	
	pLog->data1 = model_id;									// 宠物ID
	pLog->data2 = num;										// 操作数量
	
	pLog->sdata1 = pGiveUser->getStringField("nick");		// 目标玩家昵称
	
	pLog->create_time = sTools.GetCurDateTime();
	sChannelMgr.addCenterLogDB(pLog);
	sChannelMgr.freeDumyCenterLog(pLog);
	Log.Debug("CenterHappyFarmManager::HappyFarmRecvLog","user pid[%u]", recv_pid);
	return true;
}

// 发送系统邮件
uint8 GameLogicManager::SendSystemMail(String strParmars)
{
	if(!strParmars.compare(""))
		return enInvitePlayerResult_Failed;
	
	Json::Value json_par;
	Json::Reader reader;
	reader.parse(strParmars, json_par);
	
	if(!json_par.size())
		return enInvitePlayerResult_Failed;
	
	Log.Debug("CRMessageManager::SendSystemMail","strParmars[%s] json size[%u]", strParmars.c_str(), json_par.size());
	
	CRUser targetUser;
	uint32 model_id = 0;
	uint32 num = 0;
	uint32 expire_time;
	uint32 sub_type = 0;
	
	// 奖励的模式ID和数量
	if(!json_par.isMember("model_id"))
		return enInvitePlayerResult_ErrorModelID;
	
	if(!json_par.isMember("num"))
		return enInvitePlayerResult_ErrorNum;
	
	if(!json_par.isMember("expire_time"))
		return enInvitePlayerResult_ErrorNum;
	
	model_id = json_par["model_id"].asUInt();			// 模式ID
	num = json_par["num"].asUInt();						// 数量
	expire_time = json_par["expire_time"].asUInt();		// 数量
	
	if(json_par.isMember("sub_type"))
		sub_type = json_par["sub_type"].asUInt();
	
	// 邮件标题和内容
	String szTitle = "";
	String szContent = "";
	if(json_par.isMember("title"))
		szTitle = ServerDatabase.EscapeString(json_par["title"].asString());
	
	if(json_par.isMember("content"))
		szContent = json_par["content"].asString();
	
	if(szTitle == "")
		return enInvitePlayerResult_EmpryTitle;
	
	if(szContent == "")
		return enInvitePlayerResult_EmptyContent;
	
	// 邮件接收方PID
	uint32 target_id = 0;
	if(json_par.isMember("target_id"))
		target_id = json_par["target_id"].asUInt();
	
	// 没有找到目标玩家
	if(target_id == 0)
		return enInvitePlayerResult_ErrorDestPid;
	
	if(target_id)
	{
		if(!sCRUsersMgr.GetCRUser(target_id, &targetUser))
			return enInvitePlayerResult_ErrorDestPid;
	}
	
	// 发送邮件给源玩家
	std::map<uint32,uint32> mapItems;
	mapItems.insert(std::make_pair(model_id, num));
	
	GameMail *pMail = sChannelMgr.newDumyMail();
	pMail->group_id = sChannelMgr.getGroupID(); // 邮件组ID
	pMail->status = Mail::MailStatusRecv; 		// 邮件状态
	pMail->recv_serial = target_id; 			// 接收方用户ID
	pMail->title = szTitle; 					// 标题
	
	uint32 hasitem = 0;							// 是否有附件
	Json::Value val;
	
	if(mapItems.size())
	{
		char str[16];
		std::map<uint32,uint32>::iterator iter,ei = mapItems.end();
		for (iter=mapItems.begin(); iter!=ei; iter++)
		{
			if (iter->first==0 || iter->second==0)
				continue;
			sprintf(str, "%d", iter->first);
			hasitem = 1;
			val["items"][str] = iter->second;
		}
	}
	
	val["content"] = szContent;
	
	Json::FastWriter w;
	pMail->contenct = ServerDatabase.EscapeString(w.write(val)); 	// 内容
	
	pMail->data1 = hasitem;					// 是佛有添加附件（0 否 1 有）
	pMail->data2 = sub_type;				// 添加原因（可用来当做日志类子型用）
	
	pMail->create_time = time(0); 			// 创建时间
	pMail->expiration_time = expire_time; 	// 过期时间
	
	sChannelMgr.addMailDB(pMail);
	sChannelMgr.freeDumyMail(pMail);
	
	std::list<UserPtr> lstUsers;
	sUserMgr.getUserList(&lstUsers, 0, 1, "`platform_id` = %u", target_id);
	if(!lstUsers.empty())
	{
		UserPtr pUser = lstUsers.front();
		if (!pUser.isNull())
		{
			CharPtr pRecvChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
			if(!pRecvChr.isNull())
			{// 角色在线发送邮件未读数量
				WorldPacket packet;
				if (sProtocolsMgr.CreateSendUnreadMailNumberPacket(&packet, pUser))
					sGLMgr.SendProtocolsToChr(pRecvChr, &packet);
			}
		}
	}
	
	return enInvitePlayerResult_Sucess;
}

// 发送系统邮件
uint8 GameLogicManager::SendSystemMailNew(String strParmars)
{
	if(strParmars == "")
		return enInvitePlayerResult_Failed;
	
	Json::Value valPar;
	Json::Reader reader;
	reader.parse(strParmars, valPar);
	Log.Debug("CRMessageManager::SendSystemMailNew","strParmars[%s] json size[%u]", strParmars.c_str(), valPar.size());
	
	try
	{
		if(!valPar.isMember("pid") || !valPar.isMember("title") || !valPar.isMember("content"))
			return 2;
		
		uint32 pid = valPar["pid"].asUInt();
		String strTitle = valPar["title"].asString();
		String strContent = valPar["content"].asString();
		if(pid == 0 || strTitle == "" || strContent == "")
			return 3;
		
		uint32 gz_id = 0;
		if(valPar.isMember("gz_id"))
			gz_id = valPar["gz_id"].asUInt();
		
		// 发送邮件给源玩家
		std::map<uint32,uint32> mapItems;
		if(valPar.isMember("items"))
		{
			for(Json::Value::iterator iterVal=valPar["items"].begin(); iterVal!=valPar["items"].end(); ++iterVal)
			{
				mapItems.insert(std::make_pair((*iterVal)["msid"].asUInt(), (*iterVal)["num"].asUInt()));
			}
		}
		
		GameMail *pMail = sChannelMgr.newDumyMail();
		pMail->group_id = sChannelMgr.getGroupID(); // 邮件组ID
		pMail->status = Mail::MailStatusRecv; 		// 邮件状态
		pMail->recv_serial = pid; 					// 接收方用户ID
		pMail->title = strTitle; 					// 标题
		
		uint32 hasitem = 0;							// 是否有附件
		Json::Value val;
		
		if(mapItems.size())
		{
			char str[16];
			std::map<uint32,uint32>::iterator iter,ei = mapItems.end();
			for (iter=mapItems.begin(); iter!=ei; iter++)
			{
				if (iter->first==0 || iter->second==0)
					continue;
				sprintf(str, "%d", iter->first);
				hasitem = 1;
				val["items"][str] = iter->second;
			}
		}
		
		val["content"] = strContent;
		
		Json::FastWriter w;
		pMail->contenct = ServerDatabase.EscapeString(w.write(val)); 	// 内容
		
		pMail->data1 = hasitem;					// 是佛有添加附件（0 否 1 有）
		
		pMail->create_time = time(0); 			// 创建时间
		
		uint32 expire_time = time(0) + (86400 * 30);	// 默认30天过期
		if(valPar.isMember("expiry_date"))
		{
			String strExpiryData = valPar["expiry_date"].asString();
			expire_time = GetDateTimeSeconds(strExpiryData);
		}
		else if(valPar.isMember("expiry_days"))
		{
			expire_time = time(0) + 86400 * valPar["expiry_days"].asUInt();
		}
		
		pMail->expiration_time = expire_time; 	// 过期时间
		
		sChannelMgr.addMailDB(pMail);
		sChannelMgr.freeDumyMail(pMail);
		
		if(gz_id)
		{
			std::list<UserPtr> lstUsers;
			sUserMgr.getUserList(&lstUsers, 0, 1, "`platform_id` = %u and `gz_id` = %u", pid, gz_id);
			if(!lstUsers.empty())
			{
				UserPtr pUser = lstUsers.front();
				if (!pUser.isNull())
				{
					CharPtr pRecvChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
					if(!pRecvChr.isNull())
					{// 角色在线发送邮件未读数量
						WorldPacket packet;
						if (sProtocolsMgr.CreateSendUnreadMailNumberPacket(&packet, pUser))
							sGLMgr.SendProtocolsToChr(pRecvChr, &packet);
					}
				}
			}
		}
	}
	catch(exception & e)
	{
		return 4;
	}
	
	return enInvitePlayerResult_Sucess;
}

// 赠送道具给玩家
uint8 GameLogicManager::PlayerGiveItemsFromGWToPlayer(String strParmars)
{
	if(!strParmars.compare(""))
		return enInvitePlayerResult_Failed;
	
	Json::Value json_par;
	Json::Reader reader;
	reader.parse(strParmars, json_par);
	
	if(!json_par.size())
		return enInvitePlayerResult_Failed;
	
	Log.Debug("CRMessageManager::PlayerGiveItemsFromGWToPlayer","strParmars[%s] json size[%u]", strParmars.c_str(), json_par.size());
	
	CharPtr srcChr, targetChr;
	uint32 src_pid, target_pid;	// 源和目标角色ID
	uint32 model_id = 0;		// 赠送道具模式ID
	uint32 num = 0;				// 赠送道具数量
	
	// 奖励的模式ID和数量
	if(!json_par.isMember("model_id"))
		return enInvitePlayerResult_ErrorModelID;
	
	if(!json_par.isMember("num"))
		return enInvitePlayerResult_ErrorNum;
	
	if(!json_par.isMember("src_pid"))
		return enInvitePlayerResult_ErrorSrcPid;
	
	if(!json_par.isMember("target_pid"))
		return enInvitePlayerResult_ErrorTargetPid;
	
	model_id = json_par["model_id"].asUInt();			// 模式ID
	num = json_par["num"].asUInt();						// 数量
	src_pid = json_par["src_pid"].asUInt();			// 源角色ID
	target_pid = json_par["target_pid"].asUInt();		// 目标角色ID
	
	if(model_id == 0)
		return enInvitePlayerResult_ErrorItemModelID;
	
	if(num == 0)
		return enInvitePlayerResult_ItemNumCannotBeZero;
	
	std::list<ResourcePtr> srcUsers, targetUsers;
	sUserMgr.getDBObjects(&srcUsers, 0, 1, " platform_id = %u ", src_pid);	
	sUserMgr.getDBObjects(&targetUsers, 0, 1, " platform_id = %u ", target_pid);	
	
	if(srcUsers.empty())
		return enInvitePlayerResult_ErrorSrcPid;
	
	if(targetUsers.empty())
		return enInvitePlayerResult_ErrorTargetPid;
	
	UserPtr pSrcUser = sUserMgr.load((*srcUsers.begin())->getUInt32Field("uid"));
	if(pSrcUser.isNull())
		return enInvitePlayerResult_ErrorSrcPid;
	
	UserPtr pTargetUser = sUserMgr.load((*targetUsers.begin())->getUInt32Field("uid"));
	if(pTargetUser.isNull())
		return enInvitePlayerResult_ErrorTargetPid;
	
	// 源和目标玩家银行
	GameBank srcBank, targetBank;
	if (!sBankMgr.GetRealBank(pSrcUser, srcBank))
		return enInvitePlayerResult_ErrorSrcPid;
	
	if (!sBankMgr.GetRealBank(pTargetUser, targetBank))
		return enInvitePlayerResult_ErrorTargetPid;
	
	bool bLoadSrcBankData = false;
	bool bLoadTargetBankData = false;
	
	if(srcBank.status == CenterBankManager::BankStatusPrep && pSrcUser->getUInt32Field("gz_id") == srcBank.src_gz_id)
	{// 玩家在要查询的游戏下线
		
		bLoadSrcBankData = true;
		uint16 currGZID = 0;
		sBankMgr.JoinGameServer(pSrcUser, pSrcUser->getUInt32Field("gz_id"), &currGZID);	
	}
	
	if(targetBank.status == CenterBankManager::BankStatusPrep && pTargetUser->getUInt32Field("gz_id") == targetBank.src_gz_id)
	{// 玩家在要查询的游戏下线
		
		bLoadTargetBankData = true;
		uint16 currGZID = 0;
		sBankMgr.JoinGameServer(pTargetUser, pTargetUser->getUInt32Field("gz_id"), &currGZID);	
	}
	
	CharPtr pSrcChr = sCharMgr.load(pSrcUser->getUInt32Field("char_id"));
	if(pSrcChr.isNull())
		return enInvitePlayerResult_ErrorSrcPid;
	
	CharPtr pTargetChr = sCharMgr.load(pTargetUser->getUInt32Field("char_id"));
	if(pTargetChr.isNull())
		return enInvitePlayerResult_ErrorTargetPid;
	
	ItemModelPtr itModel = sItemModelMgr.load(model_id);
	if(itModel.isNull())
		return enInvitePlayerResult_ErrorItemModelID;
	
	if(!reduceItemNum(pSrcChr, model_id, num))	// 源玩家道具数量不足
		return enInvitePlayerResult_SrcCharNeedItemNum;
	
	// 记录目标玩家道具扣除日志
	sLogDataMgr.UpdateItemsInfoLog(pSrcChr, en_ST_CharGiveItemsFromGWToChar, model_id, en_UNT_Reduce, num, target_pid);
	
	// 获赠日志
	addItemNum(pTargetChr, model_id, num);
	sLogDataMgr.UpdateItemsInfoLog(pTargetChr, en_ST_CharGiveItemsFromGWToChar, model_id, en_UNT_Add, num, src_pid);
	
	if(bLoadSrcBankData)
	{// 释放银行数据
		sBankMgr.DisconnectServer(pSrcUser, pSrcUser->getUInt32Field("gz_id"));
	}
	
	if(bLoadTargetBankData)
	{// 释放银行数据
		sBankMgr.DisconnectServer(pTargetUser, pTargetUser->getUInt32Field("gz_id"));
	}
	
	if(model_id == ItemModel_Coins)
	{// 更新玩家用于排行的数据
		pSrcChr->setUInt32Field("record_1000", sGLMgr.GetItemNum(pSrcChr, model_id));
		pSrcChr->SaveDB();
		
		pTargetChr->setUInt32Field("record_1000", sGLMgr.GetItemNum(pTargetChr, model_id));
		pTargetChr->SaveDB();
	}
	
	return enInvitePlayerResult_Sucess;
}

// 查询物品数量
uint8 GameLogicManager::QueryPlayerItemNumber(String strParmars, String & extra_info)
{
	if(!strParmars.compare(""))
		return enInvitePlayerResult_Failed;
	
	Json::Value json_par;
	Json::Reader reader;
	reader.parse(strParmars, json_par);
	
	uint32 model_id = 0;
	uint32 target_pid = 0;
	
	// 奖励的模式ID和数量
	if(!json_par.isMember("model_id"))
		return enInvitePlayerResult_ErrorModelID;
	if(!json_par.isMember("target_pid"))
		return enInvitePlayerResult_ErrorTargetPid;
	model_id = json_par["model_id"].asUInt();
	target_pid = json_par["target_pid"].asUInt();
	
	std::list<ResourcePtr> targetUsers;
	sUserMgr.getDBObjects(&targetUsers, 0, 1, " platform_id = %u ", target_pid);	
	
	if(targetUsers.empty())
		return enInvitePlayerResult_ErrorTargetPid;
WGS_ORDER_LOCK
	
	UserPtr pTargetUser = sUserMgr.load((*targetUsers.begin())->getUInt32Field("uid"));
	if(pTargetUser.isNull())
		return enInvitePlayerResult_ErrorTargetPid;
	CharPtr pTargetChr;
	GameBank bank;
	
	if (sBankMgr.GetRealBank(pTargetUser, bank) && pTargetUser->getUInt32Field("char_id") == 0)
	{// 创建角色和银行
		pTargetChr = CreateCreature(pTargetUser, false);
		if(pTargetChr.isNull())
			return enInvitePlayerResult_ErrorTargetPid;
		sBankMgr.GetRealBank(pTargetUser, bank);
	}
	
	if(pTargetChr.isNull())
	{
		pTargetChr = sCharMgr.load(pTargetUser->getUInt32Field("char_id"));
		if(pTargetChr.isNull())
			return enInvitePlayerResult_ErrorTargetPid;
	}
	
	bool bLoadBankData = false;
	if(bank.status == CenterBankManager::BankStatusPrep && pTargetUser->getUInt32Field("gz_id") == bank.src_gz_id)
	{// 玩家在要查询的游戏下线
		
		bLoadBankData = true;
		
		uint16 currGZID = 0;
		sBankMgr.JoinGameServer(pTargetUser, pTargetUser->getUInt32Field("gz_id"), &currGZID);
	}
	
	Json::Value val;
	if(model_id == 0)
	{// 查询所有
		std::list<ItemPtr> itemList;
		pTargetChr->getItemsList(&itemList);
		
		if(itemList.size())
		{
			std::list<ItemPtr>::iterator iter;
			for(iter = itemList.begin();iter != itemList.end();++iter)
			{
				uint32 it_model = (*iter)->getUInt32Field("model_id");
				uint32 num = (*iter)->getUInt32Field("num");
				val[StringConverter::toString(it_model)] = num;
			}
		}
	}
	else
	{// 查询单个
		uint32 num = GetItemNum(pTargetChr, model_id);
		val[StringConverter::toString(model_id)] = num;
	}
	
	Json::FastWriter w;
	extra_info = w.write(val);
	
	if(bLoadBankData)
	{// 释放银行数据
		sBankMgr.DisconnectServer(pTargetUser, pTargetUser->getUInt32Field("gz_id"));
	}
	
	return enInvitePlayerResult_Sucess;
}

bool GameLogicManager::GetUserLongitudeAndLatitude(const uint32 & pid, double & longitude, double & latitude, double & altitude)
{
	return sCRGeoLocationMgr.GetUserLongitudeAndLatitude(pid, longitude, latitude, altitude);
}

// 获得玩家模糊IP地址(xxx.xxx.*)
String GameLogicManager::GetCharVagueIp(CharPtr & pChr)
{
	if(pChr.isNull())
		return "";
	
	WSSocketPtr socket = pChr->getSocket();
	if(socket.isNull())
		return "";
	
	String strVagueIp = "";
	String strOrgIP = socket->GetIP();
	std::vector< String > strVIp = StringUtil::split(strOrgIP, ".");
	if(strVIp.size() == 4)
	{
		strVagueIp += strVIp[0];
		strVagueIp += ".";
		strVagueIp += strVIp[1];
		strVagueIp += ".";
		strVagueIp += "*";
		strVagueIp += ".";
		strVagueIp += "*";
	}
	
	return strVagueIp;
}

// 购买打包商品
bool GameLogicManager::UserBuyUnionGoods(CharPtr & pChr, const uint32 & goods_id, const uint32 & buy_count, std::map<uint32, uint32> * mapGoods)
{
	if(pChr.isNull())
		return false;
	
	UserPtr user = sUserMgr.load(pChr->getUInt32Field("userid"));
	if(user.isNull())
		return false;
	
	AICreatureBaseInterface * pAiChrInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(!pAiChrInfe)
		return false;
	
	stBuyUnionGoods stBUG = sXmlDataMgr.GetUnionGoodsByID(goods_id);
	
	String strItems = stBUG.items;
	std::vector<String> strVec = StringUtil::split(strItems, ",");
	if(strVec.empty())
		return false;
	
	uint32 curTime = time(0);
	
	std::vector<String>::iterator iter, ei = strVec.end();
	for(iter = strVec.begin(); iter!=ei; ++iter)
	{
		std::vector<String> strVec2 = StringUtil::split(*iter, ":");
		if(strVec2.size() != 2)
			return false;
		
		uint32 model_id = StringConverter::parseUnsignedInt(strVec2[0]);
		uint32 real_num = StringConverter::parseUnsignedInt(strVec2[1]) * buy_count;
		
		mapGoods->insert(std::make_pair(model_id, real_num));
		
		if(model_id >= ItemModel_Coins)
		{// 加货币
			sGLMgr.addItemNum(pChr, model_id, real_num);
			sLogDataMgr.UpdateItemsByUserBuyLog(pChr, model_id, real_num);
		}
		else
		{// 加VIP道具
			uint32 item_modelID = 0;
			uint32 item_num = 0;
			
			WorldPacket packet;
			if (model_id < ItemModel_Coins && model_id > 500)
			{// 购买各种VIP卡或礼包
				// vip卡ID
				VIPCard vipCard = sVipCardMgr.GetVipCard(model_id);
				if (0 == vipCard.id)
					return false;
				
				// 是否可购买更多
				if ((vipCard.flag & en_VipFlag_NoMore) && 
					sVipCardMgr.HaveVIPCard(pChr, model_id))
					return false;
				
				if (vipCard.type == en_VipType_Body)
				{// 形象
					uint32 bodyid = vipCard.money;
					pAiChrInfe->AddCreatureBody(bodyid, curTime + (vipCard.days*60*60*24));
					pChr->setUInt32Field("id", bodyid);
					if (sProtocolsMgr.CreateBodyListPacket(&packet, pChr))
						sGLMgr.SendProtocolsToChr(pChr, &packet);
					vipCard.money = 0;
					vipCard.coins *= real_num;
				}
				else
				{
					vipCard.coins *= real_num;
					vipCard.money *= real_num;
					vipCard.days *= real_num;
					vipCard.morraNum *= real_num;
					vipCard.bugle *= real_num;
					vipCard.signin *= real_num;					
					pAiChrInfe->AddNewVIPInfo(vipCard);
					if (vipCard.type == en_VipType_Welfare)
						sGLMgr.NoticeWelfare(pChr);
				}
				
				pAiChrInfe->SetXMLData("USERBUYVIP_TIME",curTime);
				pChr->SaveDB();
				
				if (vipCard.type == en_VipType_FirstBuy)
				{// 作首充标记
					sBankMgr.AddPublicData(user, en_PublicData_FirstBuy, real_num, en_ST_Gateway_Buy);
					sBankMgr.SetPublicData(user, en_PublicData_FirstBuyTimer, curTime);
					WSSocketPtr socket = pChr->getSocket();
					if (!socket.isNull() && sProtocolsMgr.CreateTellToDoPacket(&packet, en_RemindType_CloseFirstBuy))
						socket->SendPacket(&packet);
				}
				
				if(vipCard.coins)
				{
					item_num = vipCard.coins;
					item_modelID = ItemModel_Coins;					
				}
				else
				{
					item_modelID = ItemModel_Golds;
					item_num = vipCard.money;
				}
				
				// 添加喇叭
				if (vipCard.bugle)
				{
					sGLMgr.addItemNum(pChr, ItemModel_Bugle, vipCard.bugle);
					sLogDataMgr.UpdateItemsByUserBuyLog(pChr, ItemModel_Bugle, vipCard.bugle);
				}
				
				// 添加签到卡
				if (vipCard.signin)
				{
					sGLMgr.addItemNum(pChr, ItemModel_BuQianKa, vipCard.signin);
					sLogDataMgr.UpdateItemsByUserBuyLog(pChr, ItemModel_BuQianKa, vipCard.signin);
				}
				
				// 添加红包
				if (vipCard.hongbao)
				{
					uint32 mygz_id = user->getUInt32Field("gz_id");
					uint32 give_id1 = sXmlDataMgr.GetConfXMLValue("BUYVIP_GIVEHONGBAO1");
					uint32 give_id2 = sXmlDataMgr.GetConfXMLValue("BUYVIP_GIVEHONGBAO2");
					uint32 give_id3 = sXmlDataMgr.GetConfXMLValue("BUYVIP_GIVEHONGBAO3");
					if ((give_id1 == 0 && give_id2 == 0 && give_id3 == 0) || (mygz_id == give_id1 || mygz_id == give_id2 || mygz_id == give_id3))
					{
						sGLMgr.addItemNum(pChr, ItemModel_Lottery, vipCard.hongbao);
						sLogDataMgr.UpdateItemsByUserBuyLog(pChr, ItemModel_Lottery, vipCard.hongbao);
					}
				}
			}
			
			// 封装物品
			ItemModelPtr pIModel = sItemModelMgr.load(item_modelID);
			if(pIModel.isNull())
				return false;			
			
			if(item_modelID == ItemModel_Coins)
			{// 购买的铜钱
				sGLMgr.addItemNum(pChr, item_modelID, item_num);	
			}
			else if (pIModel->getUInt32Field("type") == 1 && pIModel->getUInt32Field("sub_type") == 1)
			{
				sGLMgr.AddMammonCard(pChr, item_modelID, item_num);
			}
			else
			{
				if (pIModel->getUInt32Field("type") != 2)
				{
					uint32 base = pIModel->getUInt32Field("value");
					item_num *= (base?base:1);
				}
				sGLMgr.addItemNum(pChr, item_modelID, item_num);
			}
			
			// 记录日志
			sLogDataMgr.UpdateItemsByUserBuyLog(pChr, item_modelID, item_num);
		}
	}
	
	return mapGoods->size();
}

// 加上字符串斜线
void GameLogicManager::ChangeYinHaoToXian(String & strVal)
{
	String s2 = "\"";
	String s3 = "|";
	
	String::size_type pos=0;
	String::size_type a=s2.size();
	String::size_type b=s3.size();
	while((pos=strVal.find(s2,pos))!=String::npos)
	{
		strVal.erase(pos, a);
		strVal.insert(pos, s3);
		pos+=b;
	}
}

// 去掉字符串斜线
void GameLogicManager::ChangeXianToYinHao(String & strVal)
{
	// 剔除斜线
	String s2 = "|";
	String s3 = "\"";
	
	String::size_type pos=0;
	String::size_type a=s2.size();
	String::size_type b=s3.size();
	while((pos=strVal.find(s2,pos))!=String::npos)
	{
		strVal.erase(pos, a);
		strVal.insert(pos, s3);
		pos+=1;
	}
}

#define SERVERINFO_URL_SECRET 	"bAAoaafxnwHtk136C86332fA1DE11908578"
#define SERVERINFO_URL_TITLE 	"/client/pf_game_zone.php?"
#define INCOME_URL_TITLE 		"/platform/income/insert"

#define GETPOINT_XXJJC_URL_TITLE "http://pf.8z.net/third/xiuxian/getPoints"
#define SETPOINT_XXJJC_URL_TITLE "http://pf.8z.net/third/xiuxian/modifyPoints"

// 添加代理收益（对局费收益）
bool GameLogicManager::AddPlayerIncomeInfoToUrl(stIncomeInfo & stInfo)
{
	String strTitle = sXmlDataMgr.GetGatewayHttpHostAddr(stInfo.agent_id);
	strTitle += INCOME_URL_TITLE;
	
	if(stInfo.game_id == 0)
		return false;
	
	if(stInfo.gz_id && stInfo.game_id == 0)
	{
		stInfo.game_id = sGLMgr.GetTargetServerGameid(stInfo.gz_id, stInfo.agent_id);
	}
	
	Json::Value valUrl;
	valUrl["gz_id"] = stInfo.gz_id;							// 分区ID
	valUrl["game_id"] = stInfo.game_id;						// 游戏ID
	valUrl["cb_id"] = stInfo.cb_id;							// 组局ID
	valUrl["room_id"] = stInfo.join_code;					// 房间ID
	valUrl["agent_id"] = stInfo.agent_id;					// 代理商ID
	valUrl["end_time"] = sGLMgr.GetCurDate();				// 结束时间
	valUrl["loop_id"] = stInfo.loop_id;						// 轮次
	
	uint32 model_id = 0;
	uint32 num = 0;
	if(stInfo.vPlayers.size())
	{
		uint8 index = 0;
		std::vector<stIncomePlayerInfo>::iterator iter,ei =	stInfo.vPlayers.end();
		for (iter = stInfo.vPlayers.begin(); iter!=ei; ++iter)
		{
			Json::Value valPlayer;
			// valPlayer["platform_id"] = (*iter).pid;			// 玩家平台ID
			model_id = (*iter).model_id;					// 收益道具模式ID（1000 铜钱/金币 1024 钻石/房卡）
			num = (*iter).num;								// 收益道具数量
			
			valUrl["players"][index++] = (*iter).pid;
		}
	}
	
	valUrl["model_id"] = model_id;
	valUrl["num"] = num;
	
	// 参数
	String strParmars = "params=";
	Json::FastWriter w;
	strParmars += string_url_encode(w.write(valUrl));
	// Log.Debug("GameLogicManager::AddPlayerIncomeInfoToUrl","valUrl[%s] 111", w.write(valUrl).c_str());
	
	// 时间戳
	uint32 cur_time = time(0);
	String strTs = "&ts=";
	strTs += StringConverter::toString(cur_time);
	// Log.Debug("GameLogicManager::AddPlayerIncomeInfoToUrl","strTs[%s] 111", strTs.c_str());
	
	// 类型（30 游戏收益）
	uint32 type = 30;
	String strType = "&type=";
	strType += StringConverter::toString(type);
	// Log.Debug("GameLogicManager::AddPlayerIncomeInfoToUrl","strType[%s] 111", strType.c_str());
	// 签名
	CMD5 md5;
	String strSig = "&sig=";
	strSig += md5.GenerateMD5(StringConverter::toString(cur_time) + StringConverter::toString(type) + w.write(valUrl) + SERVERINFO_URL_SECRET);
	
	String strUrl = "";
	strUrl += strParmars;
	strUrl += strTs;
	strUrl += strType;
	strUrl += strSig;
	
	// Log.Debug("GameLogicManager::AddPlayerIncomeInfoToUrl","valUrl[%s] 222", strUrl.c_str());
	String recv_result = httpd_request(strTitle, REQUIRE_URL_TIMEOUT, "POST", strUrl.c_str());
	Log.Debug("GameLogicManager::AddPlayerIncomeInfoToUrl","strTitle[%s] strUrl[%s] recv_result[%s]", strTitle.c_str(), strUrl.c_str(), recv_result.c_str());
	return true;
}

// 添加代理收益（赢钱抽水收益）
bool GameLogicManager::AddPlayerIncomeInfoToUrlWithPidNum(stIncomeInfo & stInfo)
{
	String strTitle = sXmlDataMgr.GetGatewayHttpHostAddr(stInfo.agent_id);
	strTitle += INCOME_URL_TITLE;
	
	if(stInfo.game_id == 0)
		return false;
	
	Json::Value valUrl;
	valUrl["gz_id"] = stInfo.gz_id;							// 分区ID
	valUrl["game_id"] = stInfo.game_id;						// 游戏ID
	valUrl["cb_id"] = stInfo.cb_id;							// 组局ID
	valUrl["room_id"] = stInfo.join_code;					// 房间ID
	valUrl["agent_id"] = stInfo.agent_id;					// 代理商ID
	valUrl["end_time"] = sGLMgr.GetCurDateTime();			// 结束时间
	valUrl["loop_id"] = stInfo.loop_id;						// 轮次
	
	if(stInfo.agent_id == 0)
		return false;
	
	uint32 model_id = 0;
	if(stInfo.vPlayers.size())
	{
		std::vector<stIncomePlayerInfo>::iterator iter,ei =	stInfo.vPlayers.end();
		for (iter = stInfo.vPlayers.begin(); iter!=ei; ++iter)
		{
			Json::Value valPlayer;
			model_id = (*iter).model_id;					// 收益道具模式ID（1000 铜钱/金币 1024 钻石/房卡）
			
			valPlayer[0] = (*iter).num;
			valPlayer[1] = (*iter).unShouYiNum;
			
			valUrl["players"][StringConverter::toString((*iter).pid)] = valPlayer;
		}
	}
	
	valUrl["model_id"] = model_id;
	
	// 参数
	String strParmars = "params=";
	Json::FastWriter w;
	strParmars += string_url_encode(w.write(valUrl));
	// Log.Debug("GameLogicManager::AddPlayerIncomeInfoToUrlWithPidNum","valUrl[%s] 111", w.write(valUrl).c_str());
	
	// 时间戳
	uint32 cur_time = time(0);
	String strTs = "&ts=";
	strTs += StringConverter::toString(cur_time);
	// Log.Debug("GameLogicManager::AddPlayerIncomeInfoToUrlWithPidNum","strTs[%s] 111", strTs.c_str());
	
	// 类型（30 游戏收益）
	uint32 type = 30;
	String strType = "&type=";
	strType += StringConverter::toString(type);
	// Log.Debug("GameLogicManager::AddPlayerIncomeInfoToUrlWithPidNum","strType[%s] 111", strType.c_str());
	// 签名
	CMD5 md5;
	String strSig = "&sig=";
	strSig += md5.GenerateMD5(StringConverter::toString(cur_time) + StringConverter::toString(type) + w.write(valUrl) + SERVERINFO_URL_SECRET);
	
	String strUrl = "";
	strUrl += strParmars;
	strUrl += strTs;
	strUrl += strType;
	strUrl += strSig;
	
	// Log.Debug("GameLogicManager::AddPlayerIncomeInfoToUrlWithPidNum","valUrl[%s] 222", strUrl.c_str());
	String recv_result = httpd_request(strTitle, REQUIRE_URL_TIMEOUT, "POST", strUrl.c_str());
	Log.Debug("GameLogicManager::AddPlayerIncomeInfoToUrlWithPidNum","strTitle[%s] strUrl[%s] recv_result[%s]", strTitle.c_str(), strUrl.c_str(), recv_result.c_str());
	return true;
}

// 添加代理收益
bool GameLogicManager::AddPlayerChipinIncomeInfoToUrl(stIncomeInfo & stInfo)
{
	String strTitle = sXmlDataMgr.GetGatewayHttpHostAddr(stInfo.agent_id);
	strTitle += INCOME_URL_TITLE;
	
	if(stInfo.game_id == 0)
		return false;
	
	Json::Value valUrl;
	valUrl["gz_id"] = stInfo.gz_id;							// 分区ID
	valUrl["game_id"] = stInfo.game_id;						// 游戏ID
	valUrl["cb_id"] = stInfo.cb_id;							// 组局ID
	valUrl["room_id"] = stInfo.join_code;					// 房间ID
	valUrl["agent_id"] = stInfo.agent_id;					// 代理商ID
	valUrl["end_time"] = sGLMgr.GetCurDate();					// 结束时间
	valUrl["loop_id"] = stInfo.loop_id;						// 轮次
	
	uint32 model_id = 0;
	if(stInfo.vPlayers.size())
	{
		std::vector<stIncomePlayerInfo>::iterator iter,ei =	stInfo.vPlayers.end();
		for (iter = stInfo.vPlayers.begin(); iter!=ei; ++iter)
		{
			Json::Value valPlayer;
			// valPlayer["platform_id"] = (*iter).pid;		// 玩家平台ID
			model_id = (*iter).model_id;					// 收益道具模式ID（1000 铜钱/金币 1024 钻石/房卡）
			// num = (*iter).num;								// 收益道具数量
			
			valPlayer[StringConverter::toString((*iter).pid)] = (*iter).num;
			
			// valUrl["players"][index++] = valPlayer;
			
			valUrl["players"][StringConverter::toString((*iter).pid)] = (*iter).num;
		}
	}
	
	valUrl["model_id"] = model_id;
	
	// 参数
	String strParmars = "params=";
	Json::FastWriter w;
	strParmars += string_url_encode(w.write(valUrl));
	// Log.Debug("GameLogicManager::AddPlayerChipinIncomeInfoToUrl","valUrl[%s] 111", w.write(valUrl).c_str());
	
	// 时间戳
	uint32 cur_time = time(0);
	String strTs = "&ts=";
	strTs += StringConverter::toString(cur_time);
	
	// 类型（40 流水收益）
	uint32 type = 40;
	String strType = "&type=";
	strType += StringConverter::toString(type);
	
	// 签名
	CMD5 md5;
	String strSig = "&sig=";
	strSig += md5.GenerateMD5(StringConverter::toString(cur_time) + StringConverter::toString(type) + w.write(valUrl) + SERVERINFO_URL_SECRET);
	
	String strUrl = "";
	strUrl += strParmars;
	strUrl += strTs;
	strUrl += strType;
	strUrl += strSig;
	
	// Log.Debug("GameLogicManager::AddPlayerChipinIncomeInfoToUrl","valUrl[%s] 222", strUrl.c_str());
	String recv_result = httpd_request(strTitle, REQUIRE_URL_TIMEOUT, "POST", strUrl.c_str());
	Log.Debug("GameLogicManager::AddPlayerChipinIncomeInfoToUrl","strUrl[%s] recv_result[%s]", strUrl.c_str(), recv_result.c_str());
	return true;
}

// 获取代理货币数量 192.168.0.119:9090/third/platform/xxjjcGetPoints
uint32 GameLogicManager::GetAgentCoinsNum(CharPtr & pChr)
{
	if(pChr.isNull())
		return 0;
	
	UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return 0;
	
	String strTitle = GETPOINT_XXJJC_URL_TITLE;
	
	Json::Value valUrl;
	valUrl["pid"] = pUser->getUInt32Field("platform_id");	// 玩家PID
	
	// 参数
	String strParmars = "params=";
	Json::FastWriter w;
	strParmars += string_url_encode(w.write(valUrl));
	
	// 时间戳
	uint32 cur_time = time(0);
	String strTs = "&ts=";
	strTs += StringConverter::toString(cur_time);
	
	// 类型（40 流水收益）
	uint32 type = 40;
	String strType = "&type=";
	strType += StringConverter::toString(type);
	
	// 签名
	CMD5 md5;
	String strSig = "&sig=";
	strSig += md5.GenerateMD5(StringConverter::toString(cur_time) + StringConverter::toString(type) + w.write(valUrl) + SERVERINFO_URL_SECRET);
	
	String strUrl = "";
	strUrl += strParmars;
	strUrl += strTs;
	strUrl += strType;
	strUrl += strSig;
	
	String recv_result = httpd_request(strTitle, REQUIRE_URL_TIMEOUT, "POST", strUrl.c_str());
	Log.Debug("GameLogicManager::GetAgentCoinsNum","title[%s] strUrl[%s] recv_result[%s]", strTitle.c_str(), strUrl.c_str(), recv_result.c_str());
	Json::Value valRet;
	Json::Reader reader;
	reader.parse(recv_result, valRet);
	
	if(valRet.isMember("status"))
	{
		uint8 result = valRet["status"].asUInt();
		if(result == 1 && valRet.isMember("num"))
		{
			return StringConverter::parseInt(valRet["num"].asString());
		}
		else
		{// 重新请求一次
			recv_result = httpd_request(strTitle, REQUIRE_URL_TIMEOUT, "POST", strUrl.c_str());
			reader.parse(recv_result, valRet);
			if(valRet.isMember("status"))
			{
				uint8 result = valRet["status"].asUInt();
				if(result == 1 && valRet.isMember("num"))
				{
					return StringConverter::parseInt(valRet["num"].asString());
				}
			}
		}
	}
	
	return 0;
}

// 设置代理货币数量 192.168.0.119:9090/third/platform/xxjjcModifyPoints
void GameLogicManager::ChangeAgentCoinsNum(CharPtr & pChr, const int32 & num)
{
	if(pChr.isNull())
		return;
	
	UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return;
	
	String strTitle = SETPOINT_XXJJC_URL_TITLE;
	
	Json::Value valUrl;
	valUrl["pid"] = pUser->getUInt32Field("platform_id");	// 玩家PID
	valUrl["num"] = StringConverter::toString(num);			// 货币数量
	
	// 参数
	String strParmars = "params=";
	Json::FastWriter w;
	strParmars += string_url_encode(w.write(valUrl));
	
	// 时间戳
	uint32 cur_time = time(0);
	String strTs = "&ts=";
	strTs += StringConverter::toString(cur_time);
	
	// 类型（40 流水收益）
	uint32 type = 40;
	String strType = "&type=";
	strType += StringConverter::toString(type);
	
	// 签名
	CMD5 md5;
	String strSig = "&sig=";
	strSig += md5.GenerateMD5(StringConverter::toString(cur_time) + StringConverter::toString(type) + w.write(valUrl) + SERVERINFO_URL_SECRET);
	
	String strUrl = "";
	strUrl += strParmars;
	strUrl += strTs;
	strUrl += strType;
	strUrl += strSig;
	
	String recv_result = httpd_request(strTitle, REQUIRE_URL_TIMEOUT, "POST", strUrl.c_str());
	
	Json::Value valRet;
	Json::Reader reader;
	reader.parse(recv_result, valRet);
	if(valRet.isMember("status"))
	{
		uint8 result = valRet["status"].asUInt();
		if(result == 1)
		{// 修改成功
			uint32 curr_coins = sGLMgr.GetItemNum(pChr, ItemModel_Coins);
			uint32 return_coins = 0;
			if(valRet.isMember("num"))
			{
				return_coins = StringConverter::parseUnsignedInt(valRet["num"].asString());
				if(curr_coins != return_coins)
					sGLMgr.SetItemNum(pChr, ItemModel_Coins, return_coins);
			}
		}
		else
		{// 重新请求一次
			recv_result = httpd_request(strTitle, REQUIRE_URL_TIMEOUT, "POST", strUrl.c_str());
			reader.parse(recv_result, valRet);
			if(valRet.isMember("status"))
			{
				uint8 result = valRet["status"].asUInt();
				if(result == 1)
				{// 失败后请求修改成功
					uint32 curr_coins = sGLMgr.GetItemNum(pChr, ItemModel_Coins);
					uint32 return_coins = 0;
					if(valRet.isMember("num"))
					{
						return_coins = StringConverter::parseUnsignedInt(valRet["num"].asString());
						if(curr_coins != return_coins)
							sGLMgr.SetItemNum(pChr, ItemModel_Coins, return_coins);
					}
				}
			}
		}
	}
	Log.Debug("GameLogicManager::ChangeAgentCoinsNum","strTitle[%s] strUrl[%s] recv_result[%s]", strTitle.c_str(), strUrl.c_str(), recv_result.c_str());
}

// 获取服务器url信息
String GameLogicManager::GetTargetServerUrlInfo(const uint32 & gz_id, const uint32 & agent_id)
{
	// url组合（开头+参数）
	String strUrl = "";
	String strUrlTitle = sXmlDataMgr.GetGatewayHttpHostAddr(agent_id);
	strUrlTitle += SERVERINFO_URL_TITLE;
	
	String strGzid = "gz_id=";
	strGzid += StringConverter::toString(gz_id);
	
	// 时间戳
	uint32 cur_time = time(0);
	String strTs = "&ts=";
	strTs += StringConverter::toString(cur_time);
	
	CMD5 md5;
	// 签名
	String strSig = "&sig=";
	strSig += md5.GenerateMD5(StringConverter::toString(gz_id) + StringConverter::toString(cur_time) + SERVERINFO_URL_SECRET);
	
	// 组合url串
	strUrl += strUrlTitle;
	
	// GET方式追加字符串 begin
	strUrl += strGzid;
	strUrl += strTs;
	strUrl += strSig;
	
	Log.Debug("GameLogicManager::GetTargetServerUrlInfo","gz_id[%u] strUrl[%s] 111", gz_id, strUrl.c_str());
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);
	Log.Debug("GameLogicManager::GetTargetServerUrlInfo","gz_id[%u] strUrl[%s] get result[%s] 222", gz_id, strUrl.c_str(), recv_result.c_str());
	return recv_result;
}

// 获取某分区服务器http_host地址
String GameLogicManager::GetTargetHttpHost(const uint32 & gz_id, const uint32 & agent_id)
{
	String strServerInfo;
	Json::Value val;
	Json::Reader reader;
	
	Log.Debug("GameLogicManager::GetTargetHttpHost","gz_id[%u] agent_id[%u]", gz_id, agent_id);
	std::map<uint32, String>::iterator fit = m_mapTargetGzIdInfo.find(gz_id);
	if(fit == m_mapTargetGzIdInfo.end())
	{
		strServerInfo = GetTargetServerUrlInfo(gz_id, agent_id);
		Log.Debug("GameLogicManager::GetTargetHttpHost","gz_id[%u] agent_id[%u] strServerInfo[%s]", gz_id, agent_id, strServerInfo.c_str());
		
		reader.parse(strServerInfo, val);
		
		uint32 curr_time = time(0);
		val["last_updateTime"] = curr_time;
		
		Json::FastWriter w;
		m_mapTargetGzIdInfo.insert(std::make_pair(gz_id, w.write(val)));
	}
	else
	{
		strServerInfo = fit->second;
		reader.parse(strServerInfo, val);
		if(val.isMember("last_updateTime"))
		{
			uint32 last_updateTime = val["last_updateTime"].asUInt();
			uint32 curr_time = time(0);
			
			if(curr_time - last_updateTime >= 600)
			{
				strServerInfo = GetTargetServerUrlInfo(gz_id, agent_id);
				
				val.clear();
				reader.parse(strServerInfo, val);
				
				val["last_updateTime"] = curr_time;
				Json::FastWriter w;
				fit->second = w.write(val);
			}
		}
	}
	
	if(val.isMember("data"))
	{
		if(val["data"].isMember("http_host"))
			return val["data"]["http_host"].asString();
	}
	
	return "";
}

// 获取某分区服务器gameid
uint32 GameLogicManager::GetTargetServerGameid(const uint32 & gz_id, const uint32 & agent_id)
{
	String strServerInfo;
	Json::Value val;
	Json::Reader reader;
	
	std::map<uint32, String>::iterator fit = m_mapTargetGzIdInfo.find(gz_id);
	if(fit == m_mapTargetGzIdInfo.end())
	{
		strServerInfo = GetTargetServerUrlInfo(gz_id, agent_id);
		m_mapTargetGzIdInfo.insert(std::make_pair(gz_id, strServerInfo));
		
		reader.parse(strServerInfo, val);
	}
	else
	{
		strServerInfo = fit->second;
		reader.parse(strServerInfo, val);
		if(val.isMember("last_updateTime"))
		{
			uint32 last_updateTime = val["last_updateTime"].asUInt();
			uint32 curr_time = time(0);
			
			if(curr_time - last_updateTime >= 600)
			{
				strServerInfo = GetTargetServerUrlInfo(gz_id, agent_id);
				
				val.clear();
				reader.parse(strServerInfo, val);
				
				val["last_updateTime"] = curr_time;
				Json::FastWriter w;
				fit->second = w.write(val);
			}
		}
	}
	
	reader.parse(strServerInfo, val);
	if(val.isMember("data"))
	{
		if(val["data"].isMember("gameid"))
			return StringConverter::parseUnsignedInt(val["data"]["gameid"].asString());
	}
	
	return 0;
}

// 发送创建牌桌网关信息到服务器
bool GameLogicManager::SendCreateChannelGateway(CharPtr & pChr, String strData, String & strExtraData, String & strShareInfo)
{
	if(strData == "")
		return false;
	
	uint32 agent_id = 0;
	UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
	if(!pUser.isNull())
		agent_id = pUser->getUInt32Field("reg_from");
	
	Json::Value val;
	Json::Reader reader;
	
	reader.parse(strData, val);
	
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 cb_id = val["cb_id"].asUInt();
	String join_code = val["join_code"].asString();
	String strPlatform = val["platform"].asString();
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if(strHttpHost == "")
		return false;
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "create_game_channel?";			// Url方法名
	strUrl += "op=1";							// 操作
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	Log.Debug("GameLogicManager::SendCreateChannelGateway","====================================strUrl[%s] gz_id[%u]", strUrl.c_str(), gz_id);
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
	
	Json::Value val2, valExtra;
	reader.parse(recv_result, val2);
	reader.parse(strExtraData, valExtra);
	if(val2.isMember("status"))
	{
		uint8 result = val2["status"].asUInt();
		CenterBattle cb;
		if(result == 1)
		{
			sCenterBattleMgr.GetCenterBattle(cb_id, &cb);
			
			// 填入房间号
			valExtra["join_code"] = cb.join_code;
			Json::FastWriter w;
			strExtraData = w.write(valExtra);
			
			if(cb.pay_mode == enPayMode_FangZhu)
			{// 非AA制，记录房主付费信息
				Json::Value valPay, valPlayer;
				valPlayer["pid"] = cb.pid;
				
				uint32 cid = 0;
				if(!pChr.isNull())
				{
					gz_id = pChr->getUInt32Field("gz_id");
					cid = pChr->getHandle();
				}
				
				valPlayer["cid"] = cid;
				valPlayer["gz_id"] = gz_id;
				
				valPlayer["model_id"] = cb.data1;
				valPlayer["num"] = cb.data2;
				
				valPay[0] = valPlayer;
				
				Json::FastWriter w;
				cb.sdata4 = w.write(valPay);
			}
		}
		
		WorldPacket packet;
		if(sProtocolsMgr.CreateGameBattleResultPacket(&packet, cb.cb_id, cb.join_code, result))
			SendProtocolsToChr(pChr, &packet);
		if(sProtocolsMgr.CreateCenterBattleInfoPacket(&packet, cb))
			SendProtocolsToChr(pChr, &packet);
		
		// 获取分享内容
		strShareInfo = GetWXShareInfo(cb, strPlatform);
	}
	
	Log.Debug("GameLogicManager::SendCreateChannelGateway","strUrl[%s] recv_result[%s]", strUrl.c_str(), recv_result.c_str());
	return true;
}

// 发送创建比赛网关信息到服务器
uint8 GameLogicManager::SendCreateGameMatchGateway(CharPtr & pChr, String strData, String & strExtraData, String & strShareInfo)
{
	if (strData == "")
		return false;

	uint32 agent_id = 0;
	if (pChr.isNull() == false)
	{
		UserPtr pUser = sUserMgr.load(pChr->getUInt32Field("userid"));
		if (!pUser.isNull())
			agent_id = pUser->getUInt32Field("reg_from");
	}
	Json::Value val;
	Json::Reader reader;

	reader.parse(strData, val);
	agent_id = val["agent_id"].asUInt();
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 cb_id = val["cm_id"].asUInt();
	String join_code = val["join_code"].asString();
	String strPlatform = val["platform"].asString();
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if (strHttpHost == "")
		return false;

	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);

	strUrl += "create_game_match?";			// Url方法名
	strUrl += "op=1";							// 操作

	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts

	strUrl += "&params=";
	strUrl += strParmars;						// 参数

	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);

	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	Log.Debug("GameLogicManager::SendCreateGameMatchGateway", "====================================strUrl[%s] gz_id[%u]", strUrl.c_str(), gz_id);
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url

	Json::Value val2, valExtra;
	reader.parse(recv_result, val2);
	reader.parse(strExtraData, valExtra);
	uint8 result = 0;
	if (val2.isMember("status"))
	{
		result = val2["status"].asUInt();
		CenterBattle cb;
		if (result == 1)
		{
			sCenterBattleMgr.GetCenterBattle(cb_id, &cb);

			// 填入房间号
			valExtra["join_code"] = cb.join_code;
			Json::FastWriter w;
			strExtraData = w.write(valExtra);

			if (cb.pay_mode == enPayMode_FangZhu)
			{// 非AA制，记录房主付费信息
				Json::Value valPay, valPlayer;
				valPlayer["pid"] = cb.pid;

				uint32 cid = 0;
				if (!pChr.isNull())
				{
					gz_id = pChr->getUInt32Field("gz_id");
					cid = pChr->getHandle();
				}

				valPlayer["cid"] = cid;
				valPlayer["gz_id"] = gz_id;

				valPlayer["model_id"] = cb.data1;
				valPlayer["num"] = cb.data2;

				valPay[0] = valPlayer;

				Json::FastWriter w;
				cb.sdata4 = w.write(valPay);
			}
		}

	/*	WorldPacket packet;
		if (sProtocolsMgr.CreateGameBattleResultPacket(&packet, cb.cb_id, cb.join_code, result))
			SendProtocolsToChr(pChr, &packet);
		if (sProtocolsMgr.CreateCenterBattleInfoPacket(&packet, cb))
			SendProtocolsToChr(pChr, &packet);*/

		// 获取分享内容
		strShareInfo = GetWXShareInfo(cb, strPlatform);
	}

	Log.Debug("GameLogicManager::SendCreateGameMatchGateway", "strUrl[%s] recv_result[%s]", strUrl.c_str(), recv_result.c_str());
	return result;
}

// 发送比赛开始信息到服务器
bool GameLogicManager::SendGameMatchStartGateway( String strData, String & strExtraData)
{
	if (strData == "")
		return false;
	
	Json::Value val;
	Json::Reader reader;

	reader.parse(strData, val);

	uint32 gz_id = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if (strHttpHost == "")
		return false;

	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);

	strUrl += "notify_match_start?";			// Url方法名
	strUrl += "op=1";							// 操作

	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts

	strUrl += "&params=";
	strUrl += strParmars;						// 参数

	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);

	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	Log.Debug("GameLogicManager::SendGameMatchStartGateway", "====================================strUrl[%s] gz_id[%u]", strUrl.c_str(), gz_id);
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url

	Json::Value val2, valExtra;
	reader.parse(recv_result, val2);
	reader.parse(strExtraData, valExtra);
	if (val2.isMember("status"))
	{
		uint8 result = val2["status"].asUInt();
		CenterBattle cb;
		if (result == 1)
		{
			
			
		}

	
	}

	Log.Debug("GameLogicManager::SendGameMatchStartGateway", "strUrl[%s] recv_result[%s]", strUrl.c_str(), recv_result.c_str());
	return true;
}

// 发送创建比赛角色到服务器
bool GameLogicManager::SendGameMatchCreateCharGateway(String strData, String & strExtraData)
{
	if (strData == "")
		return false;

	Json::Value val;
	Json::Reader reader;

	reader.parse(strData, val);

	uint32 gz_id = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if (strHttpHost == "")
		return false;

	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);

	strUrl += "notify_match_create_char?";			// Url方法名
	strUrl += "op=1";							// 操作

	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts

	strUrl += "&params=";
	strUrl += strParmars;						// 参数

	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);

	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	Log.Debug("GameLogicManager::SendGameMatchCreateCharGateway", "====================================strUrl[%s] gz_id[%u]", strUrl.c_str(), gz_id);
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url

	Json::Value val2, valExtra;
	reader.parse(recv_result, val2);
	reader.parse(strExtraData, valExtra);
	if (val2.isMember("status"))
	{
		uint8 result = val2["status"].asUInt();
		CenterBattle cb;
		if (result == 1)
		{


		}


	}

	Log.Debug("GameLogicManager::SendGameMatchCreateCharGateway", "strUrl[%s] recv_result[%s]", strUrl.c_str(), recv_result.c_str());
	return true;
}

// 发送比赛解散信息到服务器
bool GameLogicManager::SendGameMatchDissolveGateway(String strData, String & strExtraData)
{
	if (strData == "")
		return false;

	Json::Value val;
	Json::Reader reader;

	reader.parse(strData, val);

	uint32 gz_id = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if (strHttpHost == "")
		return false;

	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);

	strUrl += "notify_match_Dissolve?";			// Url方法名
	strUrl += "op=1";							// 操作

	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts

	strUrl += "&params=";
	strUrl += strParmars;						// 参数

	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);

	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	Log.Debug("GameLogicManager::SendGameMatchDissolveGateway", "====================================strUrl[%s] gz_id[%u]", strUrl.c_str(), gz_id);
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url

	Json::Value val2, valExtra;
	reader.parse(recv_result, val2);
	reader.parse(strExtraData, valExtra);
	if (val2.isMember("status"))
	{
		uint8 result = val2["status"].asUInt();
		CenterBattle cb;
		if (result == 1)
		{


		}


	}

	Log.Debug("GameLogicManager::SendGameMatchDissolveGateway", "strUrl[%s] recv_result[%s]", strUrl.c_str(), recv_result.c_str());
	return true;
}

// 发送创建牌桌网关信息到服务器
bool GameLogicManager::SendSystemCreateChannelGateway(String strData)
{
	if(strData == "")
		return false;
	
	Json::Value val;
	Json::Reader reader;
	
	reader.parse(strData, val);
	
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if(strHttpHost == "")
		return false;
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "systemcreate_game_channel?";		// Url方法名
	strUrl += "op=1";							// 操作
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
	
	Json::Value val2;
	reader.parse(recv_result, val2);
	if(val2.isMember("status"))
	{
		uint8 result = val2["status"].asUInt();
		CenterBattle cb;
		if(result == 1)
		{
			return true;
		}
	}
	
	return false;
}

// 发送组局操作网关指令到服务器
uint8 GameLogicManager::SendOpCenterBattleGateway(String strData)
{
	if(strData == "")
		return 0;
	
	Json::Value val;
	Json::Reader reader;
	
	reader.parse(strData, val);
	
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if(strHttpHost == "")
		return 0;
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "operate_center_battle?";			// Url方法名（操作组局）
	strUrl += "op=1";							// 操作
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	Log.Debug("GameLogicManager::SendOpCenterBattleGateway","strData[%s] strUrl[%s]", strData.c_str(), strUrl.c_str());
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
	Log.Debug("GameLogicManager::SendOpCenterBattleGateway","strData[%s] recv_result[%s]", strData.c_str(), recv_result.c_str());
	uint8 result = enResult_Sucess;
	
	Json::Value val2;
	reader.parse(recv_result, val2);
	if(val2.isMember("status"))
	{
		result = val2["status"].asUInt();
	}
	
	return result;
}

// 处理网关组局操作
uint8 GameLogicManager::DealOperateCenterBattleGateway(String strData)
{
	if(strData == "")
		return 0;
	
	Json::Value val;
	Json::Reader reader;
	
	reader.parse(strData, val);
	
	uint32 mode = val["op_mode"].asUInt();
	uint32 channel_id = val["channel_id"].asUInt();
	
	if(mode == enCenterBattlePauseStatus_Dissolve)
	{// 房主发起解散牌桌
		
		ChannelPtr pChannel = sChannelMgr.getByHandle(channel_id);
		if(pChannel.isNull())
		{// 没有channel
			return enPauseBattle_ChannelNull;
		}
		
		AIChannelBaseInterface * pCII = TO_CHANNEL_BASE_INTERFACE(pChannel->getAIInterface());
		if(!pCII)
		{
			return enPauseBattle_ChannelNull;
		}
		
		if(!pCII->DissolveChannel())
		{// 解散失败
			return enKickPlayer_DissolveFailed;
		}
	}
	
	return enResult_Sucess;
}

// 发送加钱处理到网关
uint8 GameLogicManager::SendAddItemGateway(String strData)
{
	if(strData == "")
		return 0;
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if(strHttpHost == "")
		return 0;
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "add_items?";						// Url方法名（操作组局）
	strUrl += "op=1";							// 操作
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	Log.Debug("GameLogicManager::SendOpCenterBattleGateway","strData[%s] strUrl[%s]", strData.c_str(), strUrl.c_str());
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
	Log.Debug("GameLogicManager::SendOpCenterBattleGateway","strData[%s] recv_result[%s]", strData.c_str(), recv_result.c_str());
	uint8 result = enResult_Sucess;
	
	Json::Value val2;
	reader.parse(recv_result, val2);
	if(val2.isMember("status"))
	{
		result = val2["status"].asUInt();
	}
	
	return result;
}

// 处理网关加钱操作
uint8 GameLogicManager::AddItemFromGatewayToPlayer(String strData)
{
	if(strData == "")
		return 0;
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	uint32 char_id = val["cid"].asUInt();
	CharPtr pChr = sCharMgr.load(char_id);
	if(pChr.isNull())
		return 0;
	
	uint32 pid = val["pid"].asUInt();
	uint32 model_id = val["model_id"].asUInt();
	uint32 num = val["num"].asUInt();
	uint32 cb_id = val["cb_id"].asUInt();
	
	String strTitle = val["mail_title"].asString();
	String content = val["content"].asString();
	
	sGLMgr.addItemNum(pChr, model_id, num);
	sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_ReturnCenterBattleOpenCoins, model_id, en_UNT_Add, num, cb_id);
	
	std::map<uint32, uint32> mapItems;
	sGLMgr.CreateMail(pid, strTitle.c_str(), content.c_str(), 0, en_ST_ReturnCenterBattleOpenCoins, &mapItems);
	return 1;
}

// 处理网关加钱操作
uint8 GameLogicManager::OperatorItemFromGatewayToPlayer(String strData)
{
	if(strData == "")
		return 0;
	
	Log.Debug("GameLogicManager::OperatorItemFromGatewayToPlayer","strData[%s]", strData.c_str());
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	if(val.empty())
		return 0;
	
	if(!val.isMember("pid") || !val.isMember("model_id") || !val.isMember("num") || !val.isMember("agent_id") || !val.isMember("club_id"))
		return 0;
	
	uint32 pid = val["pid"].asUInt();
	uint32 model_id = val["model_id"].asUInt();
	uint32 num = val["num"].asUInt();
	uint32 club_id = val["club_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	if(pid == 0 || model_id == 0 || num == 0)
		return 0;
	
	GameBank bank;
	if(sBankMgr.GetRealBank(pid, bank) != enGetPlayerInfoByPid_Sucess)
		return 0;
	
	uint32 gz_id = bank.gz_id;
	if(gz_id == 0)
	{// 银行缓存数据
		if(model_id == ItemModel_DiamondOpen)
		{// 目前只处理房卡
			if(bank.item9 < num)
				return 0;
			
			bank.item9 -= num;
			sChannelMgr.updateBankDB(&bank);
			
			// sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_CenterClubCreateUse, model_id, en_UNT_Reduce, num, club_id);
		}
		else
		{
			return 0;
		}
	}
	else
	{// 在某个游戏服务中
		uint32 game_id = GetTargetServerGameid(gz_id);
		if(sXmlDataMgr.IsInGameIds(game_id))
		{// 在当前服务器，直接扣除
			std::list<UserPtr> lstUser;
			sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u AND `gz_id`=%u", pid, gz_id);
			if(lstUser.empty())
				return 0;
			
			UserPtr pUser = *lstUser.begin();
			if(pUser.isNull())
				return 0;
			
			CharPtr pChr = sCharMgr.load(pUser->getUInt32Field("char_id"));
			if(pChr.isNull())
				return 0;
			
			if(!sGLMgr.reduceItemNum(pChr, model_id, num))
				return 0;
			
			sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_CenterClubCreateUse, model_id, en_UNT_Reduce, num, club_id);
			Log.Debug("GameLogicManager::OperatorItemFromGatewayToPlayer","char[%u] model_id[%u] num[%u]", pChr->getHandle(), model_id, num);
			return 1;
		}
		else
		{// 不在当前服务器，发送网关扣除
			String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
			if(strHttpHost == "")
				return 0;
			
			// Url头
			String strUrl = strHttpHost;
			String strParmars = string_url_encode(strData);
			
			strUrl += "operator_items?";				// Url方法名（操作道具）
			strUrl += "op=1";							// 操作
			
			uint32 ts = time(0);
			String strTs = StringConverter::toString(ts);
			strUrl += "&ts=";
			strUrl += strTs;							// 时间戳ts
			
			strUrl += "&params=";
			strUrl += strParmars;						// 参数
			
			String strOp = "1";
			CMD5 md5;
			String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
			
			strUrl += "&sig=";
			strUrl += strSig;							// 签名
			Log.Debug("GameLogicManager::OperatorItemFromGatewayToPlayer","strData[%s] strUrl[%s]", strData.c_str(), strUrl.c_str());
			String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
			Log.Debug("GameLogicManager::OperatorItemFromGatewayToPlayer","recv_result[%s]", recv_result.c_str());
			
			Json::Value valResult;
			reader.parse(recv_result, valResult);
			if(!valResult.isMember("status") || valResult["status"].asUInt() != 1)
				return 0;
		}
	}
	
	return 1;
}

// 处理网关查询玩家成就数据
uint8 GameLogicManager::QueryPlayerEffortsFromGateway(String strData, String & return_data)
{
	if(strData.empty())
		return 0;
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	// 参数不存在
	if(!val.isMember("pid"))
		return 0;
	if(!val.isMember("gz_id"))
		return 0;
		
	uint32 pid = val["pid"].asUInt();
	uint32 gz_id = val["gz_id"].asUInt();
	
	std::list<UserPtr> lstUser;
	sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u AND `gz_id`=%u", pid, gz_id);
	
	// 用户不存在
	if(lstUser.empty())
		return 2;
	
	UserPtr pUser = *lstUser.begin();
	if(pUser.isNull())
		return 2;
	
	CharPtr pChr = sCharMgr.load(pUser->getUInt32Field("char_id"));
	if(pChr.isNull())
		return 2;
	
	uint32 model_id = sXmlDataMgr.GetConfXMLValue("COMMON_JSONEFFECT_MODELID");
	if(!model_id)
		return 3;
	
	// 找不到该任务模式
	EffectModelPtr efModel = sEffectModelMgr.load(model_id);
	if(efModel.isNull())
		return 3;
	
	EffectPtr pEffect;
	std::list<EffectPtr> effects;
	pChr->getEffectsList(&effects);
	
	for (std::list<EffectPtr>::iterator it=effects.begin(); it!=effects.end(); it++)
	{
		if ((*it)->model->getSerial() == model_id)
		{// 获得指定任务
			pEffect = *it;
			break;
		}
	}
	
	if(pEffect.isNull())
		return 0;
	
	return_data = pEffect->getStringField("info");
	return 1;
}

// 通过网关领取指定服务器的成就奖励
bool GameLogicManager::SendGetEffortBountyByGateway(CharPtr & pChr, String strData)
{
	if(pChr.isNull() || strData.empty())
		return false;
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	// 参数不存在
	if(!val.isMember("gz_id"))
		return false;
	
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if(strHttpHost == "")
		return false;
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "get_effort_bounty?";				// Url方法名（领取成就）
	strUrl += "op=1";							// 操作
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
	uint8 result = enResult_Sucess;
	
	Json::Value val2;
	reader.parse(recv_result, val2);
	if(val2.isMember("status"))
	{
		result = val2["status"].asUInt();
		if(result == enResult_Sucess)
		{// 领取成功 发放奖励
			if(val2.isMember("data"))
			{// 解析要奖励的数量
				
				uint32 model_id = val2["data"]["model_id"].asUInt();
				uint32 num = val2["data"]["bounty_coins"].asUInt();
				if(num)
				{
					addItemNum(pChr, ItemModel_Coins, num);
					sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Effect, ItemModel_Coins, en_UNT_Add, num, ItemModel_Coins);
				}
				
				/* num = val2["data"]["bounty_coins"].asUInt();
				if(num)
				{
					addItemNum(pChr, ItemModel_DiamondOpen, num);
					sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Effect, ItemModel_DiamondOpen, en_UNT_Add, num, ItemModel_DiamondOpen);
				} */
				
				WorldPacket packet;
				if(sProtocolsMgr.CreateCommonSingleJsonEffectPacket(&packet, model_id,
									val2["data"]["status"].asUInt(),val2["data"]["complate_count"].asUInt(),val2["data"]["complate_count"].asUInt()))
					SendProtocolsToChr(pChr,&packet);
				return true;
			}
		}
	}
	
	return false;
}

// 来自网关领取成就奖励
bool GameLogicManager::GetEffortBountyFromGateway(String strData, String & return_data)
{
	if(strData.empty())
		return false;
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	// 需要传回 成就status complate_count model_id bounty_coins
	Json::Value val2;
	val2["model_id"] = val["model_id"].asUInt();
	
	uint32 platform_id = val["platform_id"].asUInt();
	uint32 gz_id = val["gz_id"].asUInt();
	
	std::list<UserPtr> lstUser;
	sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u AND `gz_id`=%u", platform_id, gz_id);
	if (lstUser.empty())
		return false;
	
	UserPtr pUser = lstUser.front();
	if (pUser.isNull())
		return false;
	
	CharPtr pChr = sCharMgr.load(pUser->getUInt32Field("char_id"));
	if(pChr.isNull())
		return false;
	
	std::list<EffectPtr> effectList;
	pChr->getEffectsList(&effectList);
	
	if(effectList.empty())
		return false;
	
	EffectPtr pEffect = *effectList.begin();
	
	Json::Value val_effort;
	reader.parse(pEffect->getStringField("info"), val_effort);
	
	bool bNeedWriting = false;
	WorldPacket packet;
	
	for (Json::Value::iterator iterVal=val_effort.begin(); iterVal!=val_effort.end(); ++iterVal)
	{
		uint32 effectModelID = (*iterVal)["model_id"].asUInt();
		if(effectModelID != val["model_id"].asUInt())
			continue;
		
		EffectModelPtr modelPtr = sEffectModelMgr.load(effectModelID);
		if(modelPtr.isNull())
			continue;
		
		// 未达到完成状态的
		if((*iterVal)["status"].asUInt() != enCommonEffectStatus_Finish)
			continue;
		
		bNeedWriting = true;
		
		// 任务完成，更新任务状态为领取
		(*iterVal)["status"] = enCommonEffectStatus_GetBounty;
		val2["status"] = (*iterVal)["status"].asUInt();
		val2["complate_count"] = (*iterVal)["complate_count"].asUInt();
		val2["bounty_coins"] = (*iterVal)["bounty_num"].asUInt();
		// val2["bounty_diamand"] = modelPtr->getUInt32Field("effect4");
		
		Log.Debug("GameLogicManager::GetEffortBountyFromGateway","model_id[%u] bounty_coins[%u]", effectModelID, (*iterVal)["bounty_num"].asUInt());
	}
	
	if(!bNeedWriting)
		return false;
	
	Json::FastWriter w;
	pEffect->setStringField("info", w.write(val_effort));
	pEffect->SaveDB();
	
	return_data = w.write(val2);
	return true;
}

// 完成平台成就
bool GameLogicManager::ComplateGameLoopPlatformEffort(CharPtr & pChr, const uint32 & extra_data)
{
	if(pChr.isNull())
		return false;
	
	Log.Debug("GameLogicManager::ComplateGameLoopPlatformEffort","char[%u]", pChr->getHandle());
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint32 agent_id = pUser->getUInt32Field("reg_from");
	uint32 game_id = 0;
	uint32 model_id = 0;
	uint32 data_gz_id = 0;
	
	std::vector<stSignleEffortInfo> vSEI = sXmlDataMgr.GetBuildEffortsStructVector(agent_id);
	std::vector<stSignleEffortInfo>::iterator itEff, eiEff = vSEI.end();
	for(itEff = vSEI.begin(); itEff!=eiEff; ++itEff)
	{
		Log.Debug("GameLogicManager::ComplateGameLoopPlatformEffort","type[%u] char gz_id[%u] gz_id[%u]", (*itEff).type, pChr->getUInt32Field("gz_id"), (*itEff).gz_id);
		if((*itEff).type == enCommonEffectType_ComplateGameLoop && pChr->getUInt32Field("gz_id") == (*itEff).gz_id)
		{// 指定分区指定类型任务
			model_id = (*itEff).model_id;
			data_gz_id = (*itEff).data_gz_id;
			game_id = GetTargetServerGameid(data_gz_id, pUser->getUInt32Field("reg_from"));
			if(sXmlDataMgr.IsInGameIds(game_id))
				return false;
			
			break;
		}
	}
	
	Log.Debug("GameLogicManager::ComplateGameLoopPlatformEffort","game_id[%u] model_id[%u] data_gz_id[%u]", game_id, model_id, data_gz_id);
	if(game_id == 0 || model_id == 0 || data_gz_id == 0)
		return false;
	
	Json::Value valData;
	valData["gz_id"] = data_gz_id;
	valData["pid"] = uint32(pUser->getUInt32Field("platform_id"));
	valData["type"] = uint32(enCommonEffectType_ComplateGameLoop);
	valData["model_id"] = model_id;
	valData["count"] = 1;
	valData["agent_id"] = agent_id;
	
	SendAddEffortFinishCountFromGateway(valData);
	return true;
}

// 完成平台当庄次数成就
bool GameLogicManager::ComplateBankerCountPlatformEffort(CharPtr & pChr)
{
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint32 agent_id = pUser->getUInt32Field("reg_from");
	uint32 game_id = 0;
	uint32 model_id = 0;
	uint32 data_gz_id = 0;
	
	Log.Debug("GameLogicManager::ComplateBankerCountPlatformEffort","char[%u] agent_id[%u]", pChr->getHandle(), agent_id);
	
	std::vector<stSignleEffortInfo> vSEI = sXmlDataMgr.GetBuildEffortsStructVector(agent_id);
	std::vector<stSignleEffortInfo>::iterator itEff, eiEff = vSEI.end();
	for(itEff = vSEI.begin(); itEff!=eiEff; ++itEff)
	{
		Log.Debug("GameLogicManager::ComplateBankerCountPlatformEffort","type[%u] char gz_id[%u] gz_id[%u]", (*itEff).type, pChr->getUInt32Field("gz_id"), (*itEff).gz_id);
		if((*itEff).type == enCommonEffectType_BankerCount && pChr->getUInt32Field("gz_id") == (*itEff).gz_id)
		{// 指定分区指定类型任务
			model_id = (*itEff).model_id;
			data_gz_id = (*itEff).data_gz_id;
			game_id = GetTargetServerGameid(data_gz_id, pUser->getUInt32Field("reg_from"));
			if(sXmlDataMgr.IsInGameIds(game_id))
				return false;
			
			break;
		}
	}
	
	Log.Debug("GameLogicManager::ComplateBankerCountPlatformEffort","game_id[%u] model_id[%u] data_gz_id[%u]", game_id, model_id, data_gz_id);
	if(game_id == 0 || model_id == 0 || data_gz_id == 0)
		return false;
	
	Json::Value valData;
	valData["gz_id"] = data_gz_id;
	valData["pid"] = uint32(pUser->getUInt32Field("platform_id"));
	valData["type"] = uint32(enCommonEffectType_BankerCount);
	valData["model_id"] = model_id;
	valData["count"] = 1;
	valData["agent_id"] = agent_id;
	
	SendAddEffortFinishCountFromGateway(valData);
	return true;
}

// 完成平台特殊牌型次数成就
bool GameLogicManager::ComplateSpecialCardsPlatformEffort(CharPtr & pChr, const uint32 & card_type)
{
	if(pChr.isNull() || !card_type)
		return false;
	
	Log.Debug("GameLogicManager::ComplateSpecialCardsPlatformEffort","char[%u]", pChr->getHandle());
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint32 agent_id = pUser->getUInt32Field("reg_from");
	uint32 game_id = 0;
	uint32 model_id = 0;
	uint32 data_gz_id = 0;
	
	std::vector<stSignleEffortInfo> vSEI = sXmlDataMgr.GetBuildEffortsStructVector(agent_id);
	std::vector<stSignleEffortInfo>::iterator itEff, eiEff = vSEI.end();
	for(itEff = vSEI.begin(); itEff!=eiEff; ++itEff)
	{
		Log.Debug("GameLogicManager::ComplateSpecialCardsPlatformEffort","type[%u] char gz_id[%u] gz_id[%u]", (*itEff).type, pChr->getUInt32Field("gz_id"), (*itEff).gz_id);
		if((*itEff).type == enCommonEffectType_SpecialCardsCount 
			&& pChr->getUInt32Field("gz_id") == (*itEff).gz_id 
			&& card_type == (*itEff).extra_data1)
		{// 指定分区指定类型任务
			model_id = (*itEff).model_id;
			data_gz_id = (*itEff).data_gz_id;
			game_id = GetTargetServerGameid(data_gz_id, pUser->getUInt32Field("reg_from"));
			if(sXmlDataMgr.IsInGameIds(game_id))
				return false;
			
			break;
		}
	}
	
	Log.Debug("GameLogicManager::ComplateSpecialCardsPlatformEffort","game_id[%u] model_id[%u] data_gz_id[%u]", game_id, model_id, data_gz_id);
	if(game_id == 0 || model_id == 0 || data_gz_id == 0)
		return false;
	
	Json::Value valData;
	valData["gz_id"] = data_gz_id;
	valData["pid"] = uint32(pUser->getUInt32Field("platform_id"));
	valData["type"] = uint32(enCommonEffectType_SpecialCardsCount);
	valData["model_id"] = model_id;
	valData["count"] = 1;
	valData["extra_data1"] = card_type;
	valData["agent_id"] = agent_id;
	
	SendAddEffortFinishCountFromGateway(valData);
	return true;
}

// 从Url获取微信分享内容
String GameLogicManager::GetWXShareInfo(CenterBattle & cb, String strPlatform)
{
	return "";
	
	// Url头
	String strUrl = "http://open.8z.net/h5/common/circle_config.php?";	// 线上环境
	
	// 分区ID
	strUrl += "gz_id=";
	strUrl += StringConverter::toString(cb.gz_id);
	
	// 游戏ID
	strUrl += "&gameId=";
	strUrl += StringConverter::toString(cb.game_id);
	
	// 房间验证码
	strUrl += "&validation=";
	strUrl += cb.join_code;
	
	// 封顶
	strUrl += "&fd=";
	strUrl += StringConverter::toString(cb.top_times);
	
	// 局数
	strUrl += "&js=";
	strUrl += StringConverter::toString(cb.limit_loop);
	
	// 平台
	strUrl += "&platform=";
	strUrl += strPlatform;
	
	// 操作方法名
	strUrl += "&action=circle_share";
	
	// 玩法选择
	strUrl += "&addDatas=";
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(cb.sdata2, val);
	val["mode_id"] = cb.mode;
	
	Json::FastWriter w;
	String encode_data = string_url_encode(w.write(val));
	strUrl += encode_data;
	
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
	Log.Debug("GetWXShareInfo","strUrl[%s] recv_result[%s]", strUrl.c_str(), recv_result.c_str());
	return recv_result;
}

// 测试机器人创建组局
bool GameLogicManager::TestRobotCreateChannel()
{
	String strData = "";
	Json::Value val;
	Json::FastWriter w;
	
	val["gz_id"] = 148;
	val["pid"] = 1000226;
	val["game_id"] = 14;
	val["mode"] = 104;
	
	String extra_data;
	String share_info;
	sCenterBattleMgr.RobotCreateCenterBattle(w.write(val), extra_data, share_info);
	return true;
}

// 测试机器人查询组局数据
bool GameLogicManager::TestRobotQueryData()
{
	Json::Value val;
	val["cb_id"] = 4073;
	
	Json::FastWriter w;
	String strParmars = w.write(val);
	
	// Url头
	String strUrl = "http://192.168.0.183:7564/common/";
	strUrl += "query_centerbattle_record?";			// Url方法名
	strUrl += "op=1";								// 操作
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;								// 时间戳ts
	
	strUrl += "&params=";
	strUrl += string_url_encode(strParmars);		// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strParmars + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
	Log.Debug("TestRobotQueryData","strUrl[%s] recv_result[%s]", strUrl.c_str(), recv_result.c_str());
	return true;
}

// 退出服务器
uint8 GameLogicManager::ExitGameServer(String strParmars)
{
	if(strParmars.empty())
		return 0;
	
	uint32 platform_id = 0;
	uint32 gz_id = 0;
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strParmars, val);
	
	if(val.isMember("platform_id"))
		platform_id = val["platform_id"].asUInt();
	
	if(val.isMember("gz_id"))
		gz_id = val["gz_id"].asUInt();
	
	if(!platform_id || !gz_id)
		return 0;
	
	std::list<UserPtr> lstUser;
	sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u AND `gz_id`=%u", platform_id, gz_id);
	if (lstUser.empty())
		return 0;
	
	UserPtr pUser = lstUser.front();
	if (pUser.isNull())
		return 0;
	
	CharPtr pChr = sCharMgr.getByHandle(pUser->getUInt32Field("char_id"));
	if(!pChr.isNull())
	{// 离开服务器前游戏内自己做的一些事情
		sGLMgr.DoSomethingBeforeExitGameServer(pChr);
	}
	
	if(!pChr.isNull())
	{
		WSSocketPtr socket = pChr->getSocket();
		if(!socket.isNull())
			socket->Disconnect();
	}
	
	// 执行退出结果
	return sBankMgr.LeaveGameServer(pUser, gz_id, gz_id);
}

// 发送退出服务器网关
bool GameLogicManager::SendExitGameServerGateway(String strData)
{
	if(strData.empty())
		return false;
	
	Json::Value val;
	Json::Reader reader;
	
	reader.parse(strData, val);
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if(strHttpHost == "")
		return false;
	
	Log.Debug("GameLogicManager::SendExitGameServerGateway","gz_id[%u] agent_id[%u] strHttpHost[%s]", gz_id, agent_id, strHttpHost.c_str());
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "exit_game_server?";			// Url方法名
	strUrl += "op=1";						// 操作
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	
	Log.Warning("GameLogicManager::SendExitGameServerGateway","strUrl[%s]", strUrl.c_str());
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
	Log.Warning("GameLogicManager::SendExitGameServerGateway","recv_result[%s]", recv_result.c_str());
	Json::Value val2;
	reader.parse(recv_result, val2);
	if(val2.isMember("status"))
	{
		uint8 result = val2["status"].asUInt();
		if(result == 1)
			return true;
	}
	
	return false;
}

// 发送网关充值数据
uint32 GameLogicManager::SendUserBuyItems(Json::Value valData)
{
	if(valData.empty())
		return false;
	
	uint32 gz_id = valData["target_gz_id"].asUInt();
	uint32 agent_id = valData["agent_id"].asUInt();
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if(strHttpHost == "")
		return false;
	
	Json::FastWriter w;
	String strData = w.write(valData);
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "userbuy_items?";				// Url方法名
	strUrl += "op=1";						// 操作
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
	Log.Debug("GameLogicManager::SendUserBuyItems","recv_result[%s]", recv_result.c_str());
	
	uint32 target_gz_id = 0;
	
	Json::Value val2;
	Json::Reader reader;
	reader.parse(recv_result, val2);
	if(val2.isMember("data"))
	{
		if(val2["data"].isMember("target_gz_id"))
			target_gz_id = val2["data"]["target_gz_id"].asUInt();
	}
	
	return target_gz_id;
}

// 充值道具
uint32 GameLogicManager::UserBuyItems(Json::Value valData, String & return_String)
{
	if(valData.empty())
		return 0;
	
	UserPtr pUser;
	uint32 user_id = valData["uid"].asUInt();
	
	if(valData.isMember("platform_id") && valData.isMember("target_gz_id"))
	{
		uint32 pid = valData["platform_id"].asUInt();
		uint32 target_gz_id = valData["target_gz_id"].asUInt();
		
		std::list<UserPtr> lstUser;
		sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u AND `gz_id`=%u", pid, target_gz_id);
		if (lstUser.empty())
			return 0;
		
		pUser = lstUser.front();
		if (pUser.isNull())
			return 0;
	}
	else
	{
		pUser = sUserMgr.load(user_id);
		if(pUser.isNull())
			return 0;
		
		valData["target_gz_id"] = pUser->getUInt32Field("gz_id");
	}
	
	uint32 char_id = pUser->getUInt32Field("char_id");
	CharPtr chr = sCharMgr.load(char_id);
	if(chr.isNull())
		return 0;
	
	AICreatureBaseInterface *pAiChrInfe = TO_CREATURE_BASE_INTERFACE(chr->getAIInterface());
	if (!pAiChrInfe)
		return 0;
	
	Json::Reader reader; 
	Json::Value json_object;
	if (!reader.parse(valData["parameter"].asString().c_str(), json_object))
		return SCR_RETURN_ERROR;
	
	std::vector<std::string> vecKeys = json_object.getMemberNames();
	std::vector<std::string>::iterator iter = vecKeys.begin();
	String strContent;
	uint32 amount = 0;
	uint32 curTime = time(0);
	WorldPacket packet;
	bool bOk = true;
	char buf[256];
	for (; iter != vecKeys.end(); ++iter)
	{
		if (StringUtil::startsWith((*iter),"addi"))
		{
			uint32 op;
			std::vector<String> strInfo = StringUtil::split(unbase64Ex(json_object[(*iter)].asString()),"|");
			// 操作	
			uint32 size = strInfo.size();
			if(size < 3)
				return 0;
			else if(size == 3)
			{
				op = 1;
			}
			else
			{
				op = StringConverter::parseUnsignedInt(strInfo[3]);
				if(op == 0)
					op = 1;
			}
			
			if(strInfo[0] == "" || strInfo[1] == "")
				return 0;
			
			bool isMammon = true;	// 财神是否生效
			bool isDiscount = false; // 是否加送铜钱
			bool isLargess = true;	// 是否送金转盘次数			
			uint32 modelId = StringConverter::parseUnsignedInt(strInfo[0]);	// 模式ID
			uint32 num = StringConverter::parseUnsignedInt(strInfo[1]);		// 数量
			if(modelId >= sXmlDataMgr.GetConfXMLValue("UNION_GOODS_START_PACKETID") 
				&& modelId <= sXmlDataMgr.GetConfXMLValue("UNION_GOODS_END_PACKETID"))
			{// 打包物品（起始和结束模式ID）
				std::map<uint32, uint32> mapGoods;
				if(!sGLMgr.UserBuyUnionGoods(chr, modelId, num, &mapGoods))
					return 0;
				
				std::map<uint32, uint32>::iterator itIt, eiIt = mapGoods.end();
				for(itIt = mapGoods.begin(); itIt!=eiIt; ++itIt)
				{
					if(itIt->first < ItemModel_Coins)
						continue;
					
					char buf[256] = "";
					sprintf(buf, sMsg.getMessage("item_num").c_str(), num, sGLMgr.GetItemName(itIt->first).c_str());
					strContent += buf;
				}
			}
			else
			{
				Log.Debug("GameLogicManager::UserBuyItems","modelId[%u] num[%u] 222", modelId, num);
				uint32 goodsId = modelId;	// 商品ID
				uint32 nBaseNumber = num;	// 基础数量
				if (modelId < ItemModel_Coins && modelId > 500)
				{// 购买各种VIP卡或礼包
					// vip卡ID
					VIPCard vipCard = sVipCardMgr.GetVipCard(modelId);
					if (0 == vipCard.id)
						return 0;
					
					if(vipCard.type == en_VipType_OutSideFlag)	// 外围权限直接通过
						return 0;
					
					// 是否可购买更多			
					if ((vipCard.flag & en_VipFlag_NoMore) && 
						sVipCardMgr.HaveVIPCard(chr, modelId))
						return 0;
					
					if (vipCard.type == en_VipType_Body)
					{// 形象
						uint32 bodyid = vipCard.money;
						pAiChrInfe->AddCreatureBody(bodyid, curTime + (vipCard.days*60*60*24));
						chr->setUInt32Field("id", bodyid);
						if (sProtocolsMgr.CreateBodyListPacket(&packet, chr))
							sGLMgr.SendProtocolsToChr(chr, &packet);
						vipCard.money = 0;
						vipCard.coins *= num;
					}
					else
					{
						Log.Debug("script_process_world_game_command_userbuyitems","modelId[%u] num[%u] 333", modelId, num);
						isDiscount = (vipCard.flag & en_VipFlag_Discount);
						vipCard.coins *= num;
						vipCard.money *=num;
						vipCard.days *= num;
						vipCard.morraNum *= num;
						vipCard.bugle *= num;
						vipCard.signin *= num;					
						pAiChrInfe->AddNewVIPInfo(vipCard);
						if (vipCard.type == en_VipType_Welfare)
						{
							sGLMgr.NoticeWelfare(chr);
							Log.Debug("script_process_world_game_command_userbuyitems","modelId[%u] num[%u] 444", modelId, num);
						}
					}
					
					//********************乐码相关*******************************//
					if(modelId >= 551 && modelId <= 576)	//打折会员
					{
						uint32 exchange_id = 0;
						uint32 pid = pUser->getUInt32Field("platform_id");
						uint32 count = sItemMgr.getExchangeDBCount(" (source = %u and data3 = 0 and status = %u)",
															pid,enExchangeStataus_YanZheng);
						if(count)
						{
							std::list<GameExchange> exchanges;
							sItemMgr.getExchangeListDB(&exchanges,0,count,"(source = %u and data3 = 0 and status = %u)",
																pid,enExchangeStataus_YanZheng);
							
							if(exchanges.size())
							{
								GameExchange gameEx = exchanges.front();
								exchange_id = gameEx.exchange_id;
								gameEx.status = enExchangeStataus_Exchaned;
								gameEx.token_user = pid;
								gameEx.token_time = sGLMgr.GetCurDateTime();
								sItemMgr.updateExchangeDB(&gameEx);
								
								WSSocketPtr socket = chr->getSocket();
								if(!socket.isNull() && sProtocolsMgr.CreateLeCardsStatusPacket(&packet,gameEx.exchange_id,gameEx.status))
									socket->SendPacket(&packet);
							}
						}
						else	//还原为普通的VIP数据
						{
							modelId = 500 + modelId % 10;
							vipCard = sVipCardMgr.GetVipCard(modelId);
							vipCard.coins *= num;
							vipCard.money *=num;
							vipCard.days *= num;
							vipCard.morraNum *= num;
							Log.Notice("script_process_world_game_command_userbuyitems","char[%u] buy error lema item!",chr->getHandle());
						}
						
						//使用日志
						sBankMgr.LeMaOpLog(pid,en_LMOM_Use,exchange_id,modelId);
						sLogDataMgr.UpdateItemsInfoLog(chr, en_ST_Gateway_Buy, modelId, en_UNT_Add,num,exchange_id);
					}
					//********************乐码相关*******************************//
					
					uint32 give_luckyEndTime = sXmlDataMgr.GetConfXMLValue("BUTVIP_GIVELUCKY_CARD_ENDTIME");
					if(!give_luckyEndTime || (give_luckyEndTime && give_luckyEndTime >= time(0)))	//充值送财神卡 活动开关
					{
						if(!sTools.IsSameDate(pAiChrInfe->GetXMLData("USERBUYVIP_TIME"),curTime))
						{
							uint32 random_num = RandomUInt(100);
							uint32 lucky_model = ItemModel_Luck;
							if(random_num >= sXmlDataMgr.GetConfXMLValue("SUPER_LUCKY_PERCENT"))	//送超级幸运卡
							{
								lucky_model = ItemModel_Luck3;
							}
							else if(random_num >= sXmlDataMgr.GetConfXMLValue("BIG_LUCKY_PERCENT"))	//送大幸运卡
							{
								lucky_model = ItemModel_Luck2;
							}
							
							ItemModelPtr modelPtr = sItemModelMgr.getByHandle(lucky_model);
							if(!modelPtr.isNull())
							{
								sGLMgr.addItemNum(chr,lucky_model,1);
								sLogDataMgr.UpdateItemsInfoLog(chr, en_ST_Hortation, lucky_model, en_UNT_Add,1,en_HSI_UserBuy);
								char msg[256] = "";
								sprintf(msg,sMsg.getMessage("BUYGIFT_MSG1").c_str(),modelPtr->getStringField("name").c_str(),1);
								WSSocketPtr socket = chr->getSocket();							
								if(!socket.isNull() && sProtocolsMgr.CreateLocalMessagePacket(&packet, msg, sMsg.getType("BUYGIFT_MSG1")))
									socket->SendPacket(&packet);
							}
						}
					}
					
					pAiChrInfe->SetXMLData("USERBUYVIP_TIME",curTime);
					chr->SaveDB();
					
					if (vipCard.type == en_VipType_FirstBuy)
					{// 作首充标记
						Log.Debug("script_process_world_game_command_userbuyitems","vip_id[%u] vip_day[%u]", vipCard.vip_id, vipCard.vip_day);
						sBankMgr.AddPublicData(pUser, en_PublicData_FirstBuy, num, en_ST_Gateway_Buy);
						sBankMgr.SetPublicData(pUser, en_PublicData_FirstBuyTimer, curTime);
						
						if(vipCard.vip_id)
						{
							// 赠送VIP天数
							VIPCard vipCardFree = sVipCardMgr.GetVipCard(vipCard.vip_id);
							if(vipCardFree.id != 0)
							{
								uint32 endTime = time(0) + vipCard.vip_day * 86400;							
								pAiChrInfe->AddVipInfo(vipCardFree, endTime);
							}
						}
						
						// 发送关闭首充通道
						WSSocketPtr socket = chr->getSocket();
						if (!socket.isNull() && sProtocolsMgr.CreateTellToDoPacket(&packet, en_RemindType_CloseFirstBuy))
							socket->SendPacket(&packet);
					}
					
					if(vipCard.coins)
					{
						num = vipCard.coins;
						modelId = ItemModel_Coins;					
					}
					else
					{
						modelId = ItemModel_Money;
						num = vipCard.money;
					}
					
					// 添加喇叭
					if (vipCard.bugle)
					{
						sGLMgr.addItemNum(chr, ItemModel_Bugle, vipCard.bugle);
						sLogDataMgr.UpdateItemsByUserBuyLog(chr, ItemModel_Bugle, vipCard.bugle);
					}
					Log.Error("aaaaa", "////////// vipCard[%u] signin[%u]", vipCard.id, vipCard.signin);
					// 添加签到卡
					if (vipCard.signin)
					{
						sGLMgr.addItemNum(chr, ItemModel_BuQianKa, vipCard.signin);
						sLogDataMgr.UpdateItemsByUserBuyLog(chr, ItemModel_BuQianKa, vipCard.signin);
					}
					
					// 添加钻石/房卡
					if(vipCard.diamand)
					{
						sGLMgr.addItemNum(chr, ItemModel_DiamondOpen, vipCard.diamand);
						sLogDataMgr.UpdateItemsByUserBuyLog(chr, ItemModel_DiamondOpen, vipCard.diamand);
					}
					
					// 添加红包
					if (vipCard.hongbao)
					{
						uint32 mygz_id = pUser->getUInt32Field("gz_id");
						uint32 give_id1 = sXmlDataMgr.GetConfXMLValue("BUYVIP_GIVEHONGBAO1");
						uint32 give_id2 = sXmlDataMgr.GetConfXMLValue("BUYVIP_GIVEHONGBAO2");
						uint32 give_id3 = sXmlDataMgr.GetConfXMLValue("BUYVIP_GIVEHONGBAO3");
						if ((give_id1 == 0 && give_id2 == 0 && give_id3 == 0) || (mygz_id == give_id1 || mygz_id == give_id2 || mygz_id == give_id3))
						{
							sGLMgr.addItemNum(chr, ItemModel_Lottery, vipCard.hongbao);
							sLogDataMgr.UpdateItemsByUserBuyLog(chr, ItemModel_Lottery, vipCard.hongbao);
						}
					}
					
					// 财神卡是生效
					isMammon = !(vipCard.flag & en_VipFlag_NoMammon);
				}
				
				// 封装物品
				memset(buf, 0, sizeof(buf));
				ItemModelPtr pIModel = sItemModelMgr.load(modelId);		// 该道具不加东西，所以不需要物品模式
				if(pIModel.isNull())
				{
					Json::Value valRet;
					valRet["target_gz_id"] = valData["target_gz_id"].asUInt();
					Json::FastWriter w;
					return_String = w.write(valRet);
					
					return valData["target_gz_id"].asUInt();			
				}
				
				if(op == 1)
				{// 加钱
					if(modelId == ItemModel_Coins || modelId == ItemModel_Money)
					{// 购买的铜钱
						uint32 n_time = time(0);
						uint32 begin_time = sXmlDataMgr.GetConfXMLValue("BUY_ACTIVITY_BEGIN");
						uint32 end_time = sXmlDataMgr.GetConfXMLValue("BUY_ACTIVITY_END");
						if(isDiscount && begin_time && end_time && n_time >= begin_time && n_time <= end_time)
						{
							isLargess = false;	// 打折商品，不能给金转盘
							num = (uint32)(num * ((float)sXmlDataMgr.GetConfXMLValue("BUY_PREFER_PERCENT") * 0.01f));						
						}
						uint32 temp = num;
						if (isMammon && sGLMgr.ReduceMammonCard(chr, 1, num))
						{	
							WorldPacket packet;
							if (sProtocolsMgr.CreateUsedMammonCardPacket(&packet, num-temp))
							{
								sGLMgr.SendProtocolsToChr(chr, &packet);
							}
						}
						
						uint32 before_changeNum = sGLMgr.GetItemNum(chr, modelId);
						sGLMgr.addItemNum(chr, modelId, num);
						
						ChannelPtr chnPtr = pAiChrInfe->GetChannelPtr();
						if(!chnPtr.isNull())
						{// 通知牌桌更新玩家数据
							AIChannelBaseInterface * pChnAiInfe = TO_CHANNEL_BASE_INTERFACE(chnPtr->getAIInterface());
							if(pChnAiInfe)
								pChnAiInfe->UpdatePlayerDataWhenBuyGoods(chr, before_changeNum);
						}
					}
					
					else if (pIModel->getUInt32Field("type") == 1 && pIModel->getUInt32Field("sub_type") == 1)
					{
						sGLMgr.AddMammonCard(chr, modelId, num);
					}
					else
					{
						if (pIModel->getUInt32Field("type") != 2)
						{
							uint32 base = pIModel->getUInt32Field("value");
							num *= (base?base:1);
						}
						sGLMgr.addItemNum(chr, modelId, num);
					}
					// 记录日志
					sLogDataMgr.UpdateItemsByUserBuyLog(chr, modelId, num);
				}
				else if(op == 2)// 扣钱
				{
					if (sGLMgr.reduceItemNum(chr, modelId, num))
					{			
						sLogDataMgr.UpdateItemsInfoLog(chr, en_ST_Gateway, modelId, en_UNT_Reduce, num);
					}
					else
					{
						bOk = false;
					}
				}

				sprintf(buf, sMsg.getMessage("item_num").c_str(), num, pIModel->getStringField("name").c_str());
				strContent += buf;
				
				/*********************-- 金转盘及土豪经验 --*********************/
				uint32 begin_act = sXmlDataMgr.GetConfXMLValue("ACTIVITY_BEGIN");
				uint32 end_act = sXmlDataMgr.GetConfXMLValue("ACTIVITY_END");			
				const BuyLargess *pBuyLargess = sXmlDataMgr.GetBuyLargess(goodsId);
				if (modelId != ItemModel_Money && pBuyLargess != NULL)
				{
					WSSocketPtr socket = chr->getSocket();
					if (isLargess && begin_act && curTime >= begin_act && curTime < end_act)
					{// 赠送金转盘次数，活动商品不参与				
						uint32 relNum = (uint32)ceil(0.0001 * nBaseNumber * pBuyLargess->number);
						uint32 largess = sBankMgr.AddPublicData(pUser, pBuyLargess->largess, relNum, en_ST_Gateway_Buy);					
						Log.Debug("script_process_world_game_command_userbuyitems","pUser[%u] AddPublicData[%u] currnum[%u]", 
							pUser->getHandle(), pBuyLargess->largess, largess);					
						if (!socket.isNull() &&  
						sProtocolsMgr.CreateCharSpecificPacket(&packet, chr->getHandle(), en_CharSpecific_BuyLargess, pBuyLargess->largess, relNum))
						{
							socket->SendPacket(&packet);
						}
					}
					// 土豪经验
					uint32 exp = (uint32)ceil(0.01 * nBaseNumber * pBuyLargess->exp);
					pAiChrInfe->AddXMLValue(TUHAO_EXPS, exp);
				}
				/*********************-- 金转盘及土豪经验 --*********************/
			}
		}
		else if (StringUtil::startsWith((*iter),"message"))
		{
			// 消息内容
			String strMsg(unbase64Ex(json_object[*iter].asString()));
			// 发信息
			sGLMgr.SendMsgToPlayer(user_id, strMsg, 1);
		}
		else if (StringUtil::startsWith((*iter),"amount"))
		{
			amount = uint32(StringConverter::parseReal(unbase64Ex(json_object[*iter].asString())) * 100.0f);
		}
	}
	
	// 记录结果日志
	sLogDataMgr.GatwayBuyResultLog(chr, strContent, amount);
	Log.Notice("script_process_world_game_command_userbuyitems","pUser[%u] buyitem %s!command result[%s]",pUser->getHandle(), bOk?"sucessfully":"failed", valData["result"].asString().c_str());
	
	Json::Value valRet;
	valRet["target_gz_id"] = valData["target_gz_id"].asUInt();
	Json::FastWriter w;
	return_String = w.write(valRet);
	
	return valData["target_gz_id"].asUInt();
}

// 获取房间人数
uint32 GameLogicManager::GetRoomPlayerCountByGzid(String strData, String & extra_info)
{
	return 0;
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	if(!val.isMember("gz_id") || !val.isMember("town_id"))
		return 0;
	
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 town_id = val["town_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	if(!gz_id || !town_id)
		return 0;
	
	uint32 player_count = 0;
	uint32 game_id = GetTargetServerGameid(gz_id, agent_id);
	if(!sXmlDataMgr.IsInGameIds(game_id))
	{// 通过网关发送获取
		Json::Value val;
		val["gz_id"] = gz_id;
		val["town_id"] = town_id;
		val["agent_id"] = agent_id;
		
		Json::FastWriter w;
		String strData = w.write(val);
		
		player_count = SendQueryTownPlayerCountToGateway(strData);
		Json::Value val_ret;
		val_ret["player_count"] = player_count;
		extra_info = w.write(val_ret);
		return player_count;
	}
	else
	{
		std::list<ResourcePtr> sock_list;
		sWSSocketMgr.getSocketList(sock_list);
		if(sock_list.empty())
			return 0;
		
		std::list<ResourcePtr>::iterator iter,ei = sock_list.end();
		for(iter = sock_list.begin(); iter != ei; ++iter)
		{
			WSSocketPtr socket = (*iter);
			if(socket.isNull() || socket->m_Char.isNull())
				continue;
			
			CharPtr pChr = socket->getCurrentCharacter();
			if (pChr.isNull())
				continue;
			
			if (pChr->getUInt32Field("gz_id") != gz_id)
				continue;
			
			AICreatureBaseInterface * pChrAiInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
			if(!pChrAiInfe)
				continue;
			
			TownPtr pTown = pChrAiInfe->GetTown();
			if(pTown.isNull() || pTown->getUInt32Field("town_id") != town_id)
				continue;
			
			++player_count;
		}
	}
	
	Json::Value val_ret;
	val_ret["player_count"] = player_count;
	
	Json::FastWriter w;
	extra_info = w.write(val_ret);
	
	return player_count;
}

// 发送网关请求房间人数
uint32 GameLogicManager::SendQueryTownPlayerCountToGateway(String strData)
{
	if(strData.empty())
		return 0;
	
	Json::Value val;
	Json::Reader reader;
	
	reader.parse(strData, val);
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 agent_id	= val["agent_id"].asUInt();
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if(strHttpHost == "")
		return 0;
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "query_town_player?";			// Url方法名
	strUrl += "op=1";						// 操作
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
	Log.Debug("GameLogicManager::SendQueryTownPlayerCountToGateway","strUrl[%s]", strUrl.c_str());
	Json::Value val2;
	reader.parse(recv_result, val2);
	if(val2.isMember("data"))
	{
		if(val2["data"].isMember("player_count"))
			return val2["data"]["player_count"].asUInt();
	}
	
	return 0;
}

// 获取玩家道具数量
uint32 GameLogicManager::GetItemNumByGzid(String strData, String & extra_info)
{
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	if(!val.isMember("gz_id") || !val.isMember("model_id") || !val.isMember("pid"))
		return 0;
	
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 model_id = val["model_id"].asUInt();
	uint32 pid = val["pid"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	
	if(!gz_id || !model_id || !pid)
		return 0;
	
	uint32 item_num = 0;
	uint32 game_id = GetTargetServerGameid(gz_id, agent_id);
	if(!sXmlDataMgr.IsInGameIds(game_id))
	{// 通过网关发送获取
		Json::Value val;
		val["gz_id"] = gz_id;
		val["model_id"] = model_id;
		val["pid"] = pid;
		val["agent_id"] = agent_id;
		
		Json::FastWriter w;
		String strData = w.write(val);
		
		item_num = SendQueryItemNumToGateway(strData);
		
		Json::Value val_ret;
		val_ret["item_num"] = item_num;
		extra_info = w.write(val_ret);
		return item_num;
	}
	else
	{
		std::list<UserPtr> lstUser;
		sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u AND `gz_id`=%u", pid, gz_id);
		if (lstUser.empty())
			return 0;
		
		UserPtr pUser = lstUser.front();
		if (pUser.isNull())
			return 0;
		
		CharPtr pChr = sCharMgr.load(pUser->getUInt32Field("char_id"));
		if(pChr.isNull())
			return 0;
		
		item_num = sGLMgr.GetItemNum(pChr, model_id);
	}
	
	Json::Value val_ret;
	val_ret["item_num"] = item_num;
	
	Json::FastWriter w;
	extra_info = w.write(val_ret);
	
	return item_num;
}

// 发送网关请求道具数量
uint32 GameLogicManager::SendQueryItemNumToGateway(String strData)
{
	if(strData.empty())
		return 0;
	
	Json::Value val;
	Json::Reader reader;
	
	reader.parse(strData, val);
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if(strHttpHost == "")
		return 0;
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "query_item_num?";			// Url方法名
	strUrl += "op=1";						// 操作
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);
	Json::Value val2;
	reader.parse(recv_result, val2);
	if(val2.isMember("data"))
	{
		if(val2["data"].isMember("item_num"))
			return val2["data"]["item_num"].asUInt();
	}
	
	return 0;
}

// 查询在线玩家数量
bool GameLogicManager::QueryOnlinePlayerCount(String strData, String & return_info)
{
	Json::Value val, valResult;
	Json::Reader reader;
	reader.parse(strData, val);
	
	if(!val.isMember("gz_id"))
		return false;
	
	uint32 gz_id = 0;
	if(val["gz_id"].isUInt())
		gz_id = val["gz_id"].asUInt();
	else
		gz_id = StringConverter::parseUnsignedInt(val["gz_id"].asString());
	
	uint32 player_num = 0;
	std::list<ResourcePtr> sock_list;
	sWSSocketMgr.getSocketList(sock_list);
	
	std::list<ResourcePtr>::iterator iter,ei = sock_list.end();
	for(iter = sock_list.begin(); iter != ei; ++iter)
	{
		WSSocketPtr socket = (*iter);
		if(socket.isNull() || socket->m_Char.isNull())
			continue;
		
		CharPtr pChr = socket->getCurrentCharacter();
		if (pChr.isNull())
			continue;
		
		if(pChr->getUInt32Field("gz_id") == gz_id)
			++player_num;
	}
	
	valResult["num"] = player_num;
	
	Json::FastWriter w;
	return_info = w.write(valResult);
	return true;
}

// 查询游戏牌桌详情
String GameLogicManager::GetGameTableListInfoByGateway(String & strData)
{
	if(strData.empty())
		return "";
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	if(val.empty())
		return "";
	
	if(!val.isMember("gz_id") || !val.isMember("room_id") || !val.isMember("hall_id"))
		return "";
	
	String return_data = "";
	
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	uint32 game_id = GetTargetServerGameid(gz_id, agent_id);
	if(!sXmlDataMgr.IsInGameIds(game_id))
	{// 通过网关发送获取
		
		String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
		if(strHttpHost == "")
			return "";
		
		// Url头
		String strUrl = strHttpHost;
		String strParmars = string_url_encode(strData);
		
		strUrl += "query_channel_list?";		// Url方法名
		strUrl += "op=1";						// 操作
		
		uint32 ts = time(0);
		String strTs = StringConverter::toString(ts);
		strUrl += "&ts=";
		strUrl += strTs;							// 时间戳ts
		
		strUrl += "&params=";
		strUrl += strParmars;						// 参数
		
		String strOp = "1";
		CMD5 md5;
		String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
		
		strUrl += "&sig=";
		strUrl += strSig;							// 签名
		
		String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);
		
		Json::Value valResult;
		reader.parse(recv_result, valResult);
		if(valResult.isMember("data"))
		{
			return_data = valResult["data"].asString();
			// 解析数据发包
			SendDDZChannelListInfo(return_data);
		}
		
		return return_data;
	}
	else
	{// 在同一服务器请求
		GetGameTableListSelf(strData, return_data);
		SendDDZChannelListInfo(return_data);
	}
	
	return return_data;
}

// 发送斗地主牌桌列表
void GameLogicManager::SendDDZChannelListInfo(String & strData)
{
	Json::Value val;
	Json::Reader reader;
    if(!reader.parse(strData, val))
		return ;
	
	if(!val.isMember("pid") || !val.isMember("gz_id"))
		return ;
	
	uint32 pid = val["pid"].asUInt();
	uint32 gz_id = val["gz_id"].asUInt();
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateDDZChannelListInfoPacket(&packet, val))
		SendProtocolsToChrByPidGzid(pid, gz_id, &packet);
}

// 网关通知俱乐部牌局超时结束
uint8 GameLogicManager::NoticeClubBattleTimesUp(String & strData)
{
	Json::Value val;
	Json::Reader reader;
    if(!reader.parse(strData, val))
		return 0;
	
	if(!val.isMember("game_id") || !val.isMember("gz_id") || !val.isMember("channels"))
		return 0;
	
	uint32 game_id = val["game_id"].asUInt();
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	if(!sXmlDataMgr.IsInGameIds(game_id))
	{// 发送网关操作
		String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
		if(strHttpHost == "")
			return 0;
		
		// Url头
		String strUrl = strHttpHost;
		String strParmars = string_url_encode(strData);
		
		strUrl += "club_battle_timesup?";		// Url方法名
		strUrl += "op=1";						// 操作
		
		uint32 ts = time(0);
		String strTs = StringConverter::toString(ts);
		strUrl += "&ts=";
		strUrl += strTs;							// 时间戳ts
		
		strUrl += "&params=";
		strUrl += strParmars;						// 参数
		
		String strOp = "1";
		CMD5 md5;
		String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
		
		strUrl += "&sig=";
		strUrl += strSig;							// 签名
		
		String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);
		
		Json::Value valResult;
		reader.parse(recv_result, valResult);
		if(valResult.isMember("status"))
		{
			if(valResult["status"].asUInt() == 1)
				return 1;
		}
	}
	else
	{// 直接操作
		for(Json::Value::iterator iterVal=val["channels"].begin(); iterVal!=val["channels"].end(); ++iterVal)
		{
			uint32 channel_id = (*iterVal).asUInt();
			ChannelPtr pChn = sChannelMgr.getByHandle(channel_id);
			if(pChn.isNull())
				continue;
			
			AIChannelBaseInterface * pChnAiInfe = TO_CHANNEL_BASE_INTERFACE(pChn->getAIInterface());
			if(!pChnAiInfe)
				continue;
			
			pChnAiInfe->ClubBattleTimesUp();
		}
		
		return 1;
	}
	
	return 0;
}

// 向目标服务器玩家发送系统消息
uint8 GameLogicManager::SendSystemMessageToTargetServer(const uint32 & pid, String & content, const uint32 & message_type, const uint32 & agent_id)
{
	if(!pid)
		return 0;
	
	GameBank bank;
	sBankMgr.GetRealBank(pid, bank);
	if(bank.gz_id == 0)
		return 0;
	
	uint32 game_id = GetTargetServerGameid(bank.gz_id, agent_id);
	if(sXmlDataMgr.IsInGameIds(game_id))
		return 0;
	
	String strHttpHost = GetTargetHttpHost(bank.gz_id, agent_id);
	if(strHttpHost == "")
		return false;
	
	Json::Value val;
	Json::FastWriter w;
	
	val["pid"] = pid;
	val["gz_id"] = bank.gz_id;
	val["content"] = content;
	val["type"] = message_type;
	val["agent_id"] = agent_id;
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(w.write(val));
	
	strUrl += "send_system_message?";			// Url方法名
	strUrl += "op=1";							// 操作
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + w.write(val) + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	Log.Debug("GameLogicManager::SendSystemMessageToTargetServer","strUrl[%s]", strUrl.c_str());
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
	Log.Debug("GameLogicManager::SendSystemMessageToTargetServer","recv_result[%s]", recv_result.c_str());
	
	return 0;
}

// 发送系统消息
uint8 GameLogicManager::SendSystemMessageFromGateway(String & strData)
{
	if(strData.empty())
		return 0;
	
	Json::Value val;
	Json::Reader reader;
	
	reader.parse(strData, val);
	if(!val.isMember("pid") || !val.isMember("gz_id") || !val.isMember("content") || !val.isMember("type"))
		return 0;
	
	uint32 pid = val["pid"].asUInt();
	uint32 gz_id = val["gz_id"].asUInt();
	String content = val["content"].asString();
	uint32 type = val["type"].asUInt();
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateLocalMessagePacket(&packet, content.c_str(), type))
		sGLMgr.SendProtocolsToChrByPidGzid(pid, gz_id, &packet);
	
	return 1;
}

// 目标服务器存储数据
uint8 GameLogicManager::ChangeCharacterOrderData(String & strData)
{
	if(strData.empty())
		return 0;
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	if(val.empty())
		return 0;
	
	if(!val.isMember("pid") || !val.isMember("gz_id") || !val.isMember("data") || !val.isMember("query_key"))
		return 0;
	
	uint32 agent_id = val["agent_id"].asUInt();
	uint32 gz_id = val["gz_id"].asUInt();
	if(gz_id == 0)
		return 0;
	
	int32 data = val["data"].asInt();
	String query_key = val["query_key"].asString();
	
	uint32 game_id = sGLMgr.GetTargetServerGameid(gz_id, agent_id);
	if(game_id == 0)
		return 0;
	
	if(sXmlDataMgr.IsInGameIds(game_id))
	{// 数据存储目标分区
		uint32 pid = val["pid"].asUInt();
		
		std::list<UserPtr> lstUser;
		sUserMgr.getUserList(&lstUser, 0, 1, "platform_id = %u AND `gz_id`=%u", pid, gz_id);
		if (lstUser.empty())
			return 0;
		
		UserPtr pUser = lstUser.front();
		if(pUser.isNull())
			return 0;
		
		CharPtr pChr = sCharMgr.load(pUser->getUInt32Field("char_id"));
		if(pChr.isNull())
			return 0;
		
		uint32 cur_data = pChr->getUInt32Field(query_key);
		if(data > 0)
		{// 增加
			pChr->setUInt32Field(query_key, cur_data + uint32(data));
		}
		else if(data < 0)
		{// 减少
			pChr->setUInt32Field(query_key, cur_data > uint32(abs(data)) ? cur_data - uint32(abs(data)) : 0);
		}
	}
	else
	{// 游戏服务器 发送网关
		// Url头
		String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
		if(strHttpHost == "")
			return false;
		
		String strUrl = strHttpHost;
		String strParmars = string_url_encode(strData);
		
		strUrl += "change_order_data?";				// Url方法名
		strUrl += "op=1";							// 操作
		
		uint32 ts = time(0);
		String strTs = StringConverter::toString(ts);
		strUrl += "&ts=";
		strUrl += strTs;							// 时间戳ts
		
		strUrl += "&params=";
		strUrl += strParmars;						// 参数
		
		String strOp = "1";
		CMD5 md5;
		String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
		
		strUrl += "&sig=";
		strUrl += strSig;							// 签名
		Log.Debug("GameLogicManager::ChangeCharacterOrderData","strUrl[%s]", strUrl.c_str());
		String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
		Log.Debug("GameLogicManager::ChangeCharacterOrderData","recv_result[%s]", recv_result.c_str());
	}
	
	return 1;
}

// 获取比赛可观战牌桌
uint32 GameLogicManager::GetMatchWatchChannelId(String & strData, String & returnData)
{
	if(strData.empty())
		return 0;
	
#ifdef CENTERMATCH
	Json::Value val, valResult;
	Json::Reader reader;
	reader.parse(strData, val);
	
	if(val.empty())
		return 0;
	
	if(!val.isMember("gz_id") || !val.isMember("cm_id"))
		return 0;
	
	uint32 cm_id = val["cm_id"].asUInt();
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 agent_id = val["agent_id"].asUInt();
	
	uint32 game_id = sGLMgr.GetTargetServerGameid(gz_id, agent_id);
	if(game_id == 0)
		return 0;
	
	if(sXmlDataMgr.IsInGameIds(game_id))
	{// 在游戏服务器，获取牌桌
		uint32 channel_id = sCenterMatchMgr.GetRandomMatchChannelId(cm_id);
		
		Json::Value valReturn;
		Json::FastWriter w;
		
		valReturn["channel_id"] = channel_id;
		returnData = w.write(valReturn);
		return channel_id;
	}
	else
	{// 不在游戏服务器，发送网关
		// Url头
		String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
		if(strHttpHost == "")
			return false;
		
		String strUrl = strHttpHost;
		String strParmars = string_url_encode(strData);
		
		strUrl += "get_match_watchchannel?";		// Url方法名
		strUrl += "op=1";							// 操作
		
		uint32 ts = time(0);
		String strTs = StringConverter::toString(ts);
		strUrl += "&ts=";
		strUrl += strTs;							// 时间戳ts
		
		strUrl += "&params=";
		strUrl += strParmars;						// 参数
		
		String strOp = "1";
		CMD5 md5;
		String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
		
		strUrl += "&sig=";
		strUrl += strSig;							// 签名
		Log.Debug("GameLogicManager::GetMatchWatchChannelId","strUrl[%s]", strUrl.c_str());
		String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
		Log.Debug("GameLogicManager::GetMatchWatchChannelId","recv_result[%s]", recv_result.c_str());
		
		reader.parse(recv_result, valResult);
		if(valResult.isMember("data"))
		{
			Json::Value valData = valResult["data"];
			if(valData.isMember("channel_id"))
			{
				return valData["channel_id"].asUInt();
			}
		}
	}
#endif
	
	return 0;
}

// 获取配置的道具物品
bool GameLogicManager::GetGatewayGoodsInfo(CharPtr & pChr)
{
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	String strUrl = sXmlDataMgr.GetGatewayHttpHostAddr(pUser->getUInt32Field("reg_from"));
	strUrl += "/platform/getModel";
	
	// 代理商ID
	String strParams = "agentid=";
	Json::FastWriter w;
	strParams += StringConverter::toString(pUser->getUInt32Field("reg_from"));
	
	Log.Debug("GameLogicManager::GetGatewayGoodsInfo","strUrl[%s]", strUrl.c_str());
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT, "POST", strParams);
	Log.Debug("GameLogicManager::GetGatewayGoodsInfo","strUrl[%s] recv_result[%s]", strUrl.c_str(), recv_result.c_str());
	
	Json::Value valResult;
	Json::Reader reader;
	reader.parse(recv_result, valResult);
	if(valResult.empty() || !valResult.isMember("ret") || !valResult.isMember("data"))
		return false;
	
	uint32 ret = valResult["ret"].asUInt();
	if(ret != 1)
		return false;
	
WGS_GATEWAY_LOCK
	uint32 model_count = sItemModelMgr.getDBCount("");
	
	std::list<ResourcePtr> models;
	sItemModelMgr.getItemModelsList(&models, 0, model_count, "");
	Log.Debug("GameLogicManager::GetGatewayGoodsInfo", "models size[%u]", models.size());
	
	for (Json::Value::iterator iterVal=valResult["data"].begin(); iterVal!=valResult["data"].end(); ++iterVal)
	{
		bool bFindModel = false;
		uint32 new_modelID = (*iterVal)["model_id"].asUInt();
		std::list<ResourcePtr>::iterator iter, ei = models.end();
		for(iter = models.begin(); iter!=ei; ++iter)
		{
			if((*iter)->getUInt32Field("model_id") == new_modelID)
			{
				bFindModel = true;
				break;
			}
		}
		
		if(!bFindModel)
		{
			String modelName = (*iterVal)["model_name"].asString();
			String modelDesc = (*iterVal)["model_desc"].asString();
			String modelUrl = (*iterVal)["model_icon"].asString();
			
			Json::Value valDesc;
			valDesc["name"] = modelName;
			valDesc["desc"] = modelDesc;
			valDesc["url"] = modelUrl;
			
			Json::FastWriter w;
			
			CharacterDatabase.WaitExecute("INSERT INTO `item_model` (`model_id`, `type`, `name`, `desc`) VALUES (%u, %u, '%s', '%s')", new_modelID, 3, modelName.c_str(), w.write(valDesc).c_str());
			Log.Debug("GameLogicManager::GetGatewayGoodsInfo","insert new item_model model_id[%u] name[%s] desc[%s]", new_modelID, modelName.c_str(), modelDesc.c_str());
		}
	}
	
	return true;
}

// 获取兑换奖励配置
std::vector<stGatewayExChangeInfo> GameLogicManager::GetExchangeBountyInfo(CharPtr & pChr)
{
	std::vector<stGatewayExChangeInfo> vExchange;
	if(pChr.isNull())
		return vExchange;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return vExchange;
	
	uint32 agent_id = pUser->getUInt32Field("reg_from");
	bool bUpdate = false;
	uint32 time_key = time(0);
	
	std::map<uint32, std::map<uint32, std::vector<stGatewayExChangeInfo> > >::iterator fit = m_mapGatewayExChangeInfo.find(agent_id);
	if(fit != m_mapGatewayExChangeInfo.end())
	{
		std::map<uint32, std::vector<stGatewayExChangeInfo> >::iterator iter, ei = fit->second.end();
		for(iter = fit->second.begin(); iter!=ei; ++iter)
		{
			if(iter->first <= time_key)
			{
				bUpdate = true;
				break;
			}
			else
			{
				vExchange = iter->second;
				break;
			}
		}
	}
	else
	{
		bUpdate = true;
	}
	
	
	if(bUpdate)
	{
		String strUrl = sXmlDataMgr.GetGatewayHttpHostAddr(pUser->getUInt32Field("reg_from"));
		strUrl += "/platform/getPrizes";
		
		// 代理商ID
		String strParams = "agentid=";
		Json::FastWriter w;
		strParams += StringConverter::toString(pUser->getUInt32Field("reg_from"));
		
		Log.Debug("GameLogicManager::GetExchangeBountyInfo","strUrl[%s]", strUrl.c_str());
		String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT, "POST", strParams);
		Log.Debug("GameLogicManager::GetExchangeBountyInfo","strUrl[%s] recv_result[%s]", strUrl.c_str(), recv_result.c_str());
		
		Json::Value valResult;
		Json::Reader reader;
		reader.parse(recv_result, valResult);
		if(valResult.empty() || !valResult.isMember("ret") || !valResult.isMember("data"))
			return vExchange;
		
		uint32 ret = valResult["ret"].asUInt();
		if(ret != 1)
			return vExchange;
		
		for (Json::Value::iterator iterVal=valResult["data"].begin(); iterVal!=valResult["data"].end(); ++iterVal)
		{
			stGatewayExChangeInfo stGEC;
			if((*iterVal)["prizes_id"].isUInt())
				stGEC.prizes_id = (*iterVal)["prizes_id"].asUInt();
			else
				stGEC.prizes_id = StringConverter::parseUnsignedInt((*iterVal)["prizes_id"].asString());
			
			if((*iterVal)["type"].isUInt())
				stGEC.type = (*iterVal)["type"].asUInt();
			else
				stGEC.type = StringConverter::parseUnsignedInt((*iterVal)["type"].asString());
			
			if((*iterVal)["num"].isUInt())
				stGEC.num = (*iterVal)["num"].asUInt();
			else
				stGEC.num = StringConverter::parseUnsignedInt((*iterVal)["num"].asString());
			
			
			if((*iterVal)["exchange_model_id"].isUInt())
				stGEC.exchange_model_id = (*iterVal)["exchange_model_id"].asUInt();
			else
				stGEC.exchange_model_id = StringConverter::parseUnsignedInt((*iterVal)["exchange_model_id"].asString());
			
			if((*iterVal)["exchange_limit"].isUInt())
				stGEC.exchange_limit = (*iterVal)["exchange_limit"].asUInt();
			else
				stGEC.exchange_limit = StringConverter::parseUnsignedInt((*iterVal)["exchange_limit"].asString());
			
			
			if((*iterVal)["exchange_model_num"].isUInt())
				stGEC.exchange_model_num = (*iterVal)["exchange_model_num"].asUInt();
			else
				stGEC.exchange_model_num = StringConverter::parseUnsignedInt((*iterVal)["exchange_model_num"].asString());
			
			if((*iterVal)["prizes_model_id"].isUInt())
				stGEC.prizes_model_id = (*iterVal)["prizes_model_id"].asUInt();
			else
				stGEC.prizes_model_id = StringConverter::parseUnsignedInt((*iterVal)["prizes_model_id"].asString());
			
			if((*iterVal)["prizes_model_num"].isUInt())
				stGEC.prizes_model_num = (*iterVal)["prizes_model_num"].asUInt();
			else
				stGEC.prizes_model_num = StringConverter::parseUnsignedInt((*iterVal)["prizes_model_num"].asString());
			
			stGEC.exchange_model_name = (*iterVal)["exchange_model_name"].asString();
			stGEC.exchange_model_image = (*iterVal)["exchange_model_image"].asString();
			stGEC.name = (*iterVal)["name"].asString();
			stGEC.desc = (*iterVal)["desc"].asString();
			stGEC.image = (*iterVal)["image"].asString();
			
			stGEC.exchange_valid_time = (*iterVal)["exchange_valid_time"].asString();
			stGEC.exchange_expire_time = (*iterVal)["exchange_expire_time"].asString();
			stGEC.useful_valid_time = (*iterVal)["useful_valid_time"].asString();
			stGEC.useful_expire_time = (*iterVal)["useful_expire_time"].asString();
			stGEC.useful_expire_relative_time = (*iterVal)["useful_expire_relative_time"].asUInt();
			
			vExchange.push_back(stGEC);
		}
		
		if(fit != m_mapGatewayExChangeInfo.end())
		{
			fit->second.clear();
			fit->second.insert(std::make_pair(time_key + 60, vExchange));
		}
		else
		{
			std::map<uint32, std::vector<stGatewayExChangeInfo> > mapExchange;
			mapExchange.insert(std::make_pair(time_key + 60, vExchange));
			
			m_mapGatewayExChangeInfo.insert(std::make_pair(agent_id, mapExchange));
		}
	}
	
	return vExchange;
}

// 兑换实物
bool GameLogicManager::ExchangeRealGoods(CharPtr & pChr, String & strData)
{
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	if(val.empty())
		return false;
	
	if(!val.isMember("id") || !val.isMember("num"))
		return false;
	
	uint32 prizes_id = val["id"].asUInt();
	uint32 num = val["num"].asUInt();
	if(num == 0)
		return false;
	
	stGatewayExChangeInfo stGEC;
	std::vector<stGatewayExChangeInfo> vGEC = GetExchangeBountyInfo(pChr);
	
	uint32 need_item_model = 0;
	uint32 need_item_num = 0;
	
	uint8 result = 1;
	do
	{
		if(vGEC.empty())
		{
			result = 2;
			break;
		}
		
		Log.Debug("GameLogicManager::ExchangeRealGoods","vGEC size[%u]", vGEC.size());
		bool bFind = false;
		std::vector<stGatewayExChangeInfo>::iterator iter, ei = vGEC.end();
		for(iter = vGEC.begin(); iter!=ei; ++iter)
		{
			Log.Debug("GameLogicManager::ExchangeRealGoods","prizes_id[%u] prizes_id2[%u]", (*iter).prizes_id, prizes_id);
			if((*iter).prizes_id == prizes_id)
			{
				bFind = true;
				stGEC = *iter;
				break;
			}
		}
		
		if(!bFind)
		{// 未找到礼品
			result = 2;
			break;
		}
		
		if(stGEC.num < num && stGEC.type == 10)
		{// 商品不够
			result =4;
			break;
		}
		
		need_item_model = stGEC.exchange_model_id;
		need_item_num = stGEC.exchange_model_num * num;
		
		if(sGLMgr.GetItemNum(pChr, need_item_model) < need_item_num)
		{// 道具不足
			result = 3;
			break;
		}
		
		Log.Debug("GameLogicManager::ExchangeRealGoods","need_item_model[%u] need_item_num[%u]", need_item_model, need_item_num);
	}while(0);
	
	if(result == 1)
	{
		// 扣钱
		if(!sGLMgr.reduceItemNum(pChr, need_item_model, need_item_num))
		{// 扣钱失败，经费不足
			result = 3;
		}
		else
		{
			String strTitle = sXmlDataMgr.GetGatewayHttpHostAddr(pUser->getUInt32Field("reg_from"));
			strTitle += "/platform/exchangePrize";
			
			// 参数
			String strParmars = "params=";
			Json::Value valUrl;
			valUrl["agentid"] = pUser->getUInt32Field("reg_from");
			valUrl["pid"] = pUser->getUInt32Field("platform_id");
			valUrl["prizes_id"] = stGEC.prizes_id;
			valUrl["num"] = num;
			valUrl["exchange_model_id"] = stGEC.exchange_model_id;
			valUrl["exchange_model_num"] = stGEC.exchange_model_num;
			
			Json::FastWriter w;
			strParmars += string_url_encode(w.write(valUrl));
			
			// 时间戳
			uint32 cur_time = time(0);
			String strTs = "&ts=";
			strTs += StringConverter::toString(cur_time);
			
			// 签名
			CMD5 md5;
			String strSig = "&sig=";
			strSig += md5.GenerateMD5(StringConverter::toString(cur_time) + w.write(valUrl) + SERVERINFO_URL_SECRET);
			
			String strUrl = "";
			strUrl += strParmars;
			strUrl += strTs;
			strUrl += strSig;
			
			Log.Debug("GameLogicManager::ExchangeRealGoods","char[%u] strTitle[%s] strparams[%s]!", pChr->getHandle(), strTitle.c_str(), strUrl.c_str());
			String recv_result = httpd_request(strTitle, REQUIRE_URL_TIMEOUT, "POST", strUrl.c_str());
			Log.Debug("GameLogicManager::ExchangeRealGoods","char[%u] recv_result[%s]!", pChr->getHandle(), recv_result.c_str());
			
			Json::Value valResult;
			reader.parse(recv_result, valResult);
			if(valResult.isMember("ret"))
			{
				uint32 ret = valResult["ret"].asUInt();
				Log.Debug("GameLogicManager::ExchangeRealGoods","ret[%u]", ret);
				if(ret != 1)
				{// 调用失败，把扣除的钱补回来
					sGLMgr.addItemNum(pChr, need_item_model, need_item_num);
					result = 0;
				}
				else
				{// 成功
					// 记录扣钱日志 角色 子类型 模式ID 加减类型 消耗数量 礼品ID 礼品模式ID
					sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_ExChangeGoods, need_item_model, en_UNT_Reduce, need_item_num, stGEC.prizes_id, stGEC.exchange_model_id, stGEC.type);
					if(stGEC.type == 20)
					{// 实物兑换
						// 添加道具，或者提交购买实物订单
						sGLMgr.addExchangeItemNum(pChr, stGEC.prizes_model_id, stGEC.prizes_model_num * num, stGEC);
					}
					else
					{// 虚拟道具兑换
						Log.Debug("GameLogicManager::ExchangeRealGoods","char[%u] prizes_id[%u] exchange sucess!", pChr->getHandle(), stGEC.prizes_id);
					}
				}
			}
		}
	}
	
	Log.Debug("GameLogicManager::ExchangeRealGoods","char[%u] prizes_id[%u] num[%u] exchange_model_id[%u] exchange_mode_num[%u] result[%u]", 
							pChr->getHandle(), stGEC.prizes_id, num, stGEC.exchange_model_id, stGEC.exchange_model_num, result);
	// 发送兑换结果
	WorldPacket packet;
	if(sProtocolsMgr.CreateExchangeGatewayGoodsPacket(&packet, stGEC.prizes_id, num, stGEC.exchange_model_id, stGEC.exchange_model_num, result))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
	
	return true;
}

// 获取玩家联系信息
bool GameLogicManager::GetUserContactInfo(CharPtr & pChr)
{
	if(pChr.isNull())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	uint32 pid = pUser->getUInt32Field("platform_id");
	
	String strTitle = sXmlDataMgr.GetGatewayHttpHostAddr(pUser->getUInt32Field("reg_from"));
	strTitle += "/platform/getUserContact";
	
	// ts
	// pid
	// sig

	// sig = md5(ts + pid + key)
	
	// 时间戳
	uint32 cur_time = time(0);
	String strUrl = "ts=";
	strUrl += StringConverter::toString(cur_time);
	
	// pid
	strUrl += "&pid=";
	strUrl += StringConverter::toString(pid);
	
	// 签名
	strUrl += "&sig=";
	CMD5 md5;
	strUrl += md5.GenerateMD5(StringConverter::toString(cur_time) + StringConverter::toString(pid) + SERVERINFO_URL_SECRET);
	
	Log.Debug("GameLogicManager::GetUserContactInfo","strTitle[%s] strUrl[%s]", strTitle.c_str(), strUrl.c_str());
	String recv_result = httpd_request(strTitle, REQUIRE_URL_TIMEOUT, "POST", strUrl.c_str());
	Log.Debug("GameLogicManager::GetUserContactInfo","recv_result[%s]", recv_result.c_str());
	
	Json::Value valResult;
	Json::Reader reader;
	reader.parse(recv_result, valResult);
	if(valResult.isMember("ret"))
	{
		String strResult = "";
		if(valResult.isMember("contact"))
		{
			Json::Value valContact = valResult["contact"];
			Json::FastWriter w;
			
			strResult = w.write(valContact);
		}
		
		WorldPacket packet;
		if(sProtocolsMgr.CreateGetUserContactPacket(&packet, pChr, strResult))
			sGLMgr.SendProtocolsToChr(pChr, &packet);
	}
	
	return true;
}

// 设置玩家联系信息
bool GameLogicManager::SetUserContactInfo(CharPtr & pChr, String & strData)
{
	if(pChr.isNull() || strData.empty())
		return false;
	
	UserPtr pUser = sUserMgr.getByHandle(pChr->getUInt32Field("userid"));
	if(pUser.isNull())
		return false;
	
	// uint32 pid = pUser->getUInt32Field("platform_id");
	
	String strTitle = sXmlDataMgr.GetGatewayHttpHostAddr(pUser->getUInt32Field("reg_from"));
	strTitle += "/platform/setUserContact";
	
	// ts
	// params
	// sig

	// sig = md5(ts + params + key)
	
	// 时间戳
	uint32 cur_time = time(0);
	String strUrl = "ts=";
	strUrl += StringConverter::toString(cur_time);
	
	// params
	String strParmars = string_url_encode(strData);
	strUrl += "&params=";
	strUrl += strParmars;
	
	// 签名
	strUrl += "&sig=";
	CMD5 md5;
	strUrl += md5.GenerateMD5(StringConverter::toString(cur_time) + strData + SERVERINFO_URL_SECRET);
	
	Log.Debug("GameLogicManager::GetUserContactInfo","strTitle[%s] strUrl[%s]", strTitle.c_str(), strUrl.c_str());
	String recv_result = httpd_request(strTitle, REQUIRE_URL_TIMEOUT, "POST", strUrl.c_str());
	Log.Debug("GameLogicManager::GetUserContactInfo","recv_result[%s]", recv_result.c_str());
	
	Json::Value valResult;
	Json::Reader reader;
	reader.parse(recv_result, valResult);
	
	uint32 ret = 0;
	if(valResult.isMember("ret"))
	{
		ret = valResult["ret"].asUInt();
	}
	
	WorldPacket packet;
	if(sProtocolsMgr.CreateSetUserContactPacket(&packet, pChr, recv_result, ret))
		sGLMgr.SendProtocolsToChr(pChr, &packet);
	
	return true;
}

// 俱乐部管理员给游戏中玩家退分
uint8 GameLogicManager::ClubManagerTuifenPlayingPlayer(String strData)
{
	if(strData == "")
		return 0;
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	if(!val.isMember("agent_id") || !val.isMember("gz_id"))
		return 0;
	
	uint32 agent_id = val["agent_id"].asUInt();
	uint32 gz_id = val["gz_id"].asUInt();
	
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if(strHttpHost == "")
		return 0;
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "club_manager_tuifen?";			// Url方法名（管理员退分）
	strUrl += "op=1";							// 操作
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	Log.Debug("GameLogicManager::ClubManagerTuifenPlayingPlayer","strUrl[%s]", strUrl.c_str());
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
	Log.Debug("GameLogicManager::ClubManagerTuifenPlayingPlayer","recv_result[%s]", recv_result.c_str());
	
	Json::Value valResult;
	reader.parse(recv_result, valResult);
	if(valResult.isMember("status"))
	{
		return valResult["status"].asUInt();
	}
	
	return 1;
}

// 玩家在游戏被管理员退分
uint8 GameLogicManager::PlayerClubTuiFenWhenPlayingComplate(String strData)
{
	if(strData == "")
		return 0;
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	if(!val.isMember("agent_id") || !val.isMember("gz_id") || !val.isMember("pid"))
		return 0;
	
	// uint32 agent_id = val["agent_id"].asUInt();
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 pid = val["pid"].asUInt();
	
	// 获得角色，角色接口，牌桌，牌桌借口，调用退分请求
	CharPtr pChr = GetCharptrByPidAndGzid(pid, gz_id);
	if(pChr.isNull())
		return 0;
	
	AICreatureBaseInterface * pChrAiInfe = TO_CREATURE_BASE_INTERFACE(pChr->getAIInterface());
	if(!pChrAiInfe)
		return 0;
	
	ChannelPtr chnPtr = pChrAiInfe->GetChannelPtr();
	if(chnPtr.isNull())
		return false;
	
	AIChannelBaseInterface * pChnAiInfe = TO_CHANNEL_BASE_INTERFACE(chnPtr->getAIInterface());
	if(!pChnAiInfe)
		return false;
	
	return pChnAiInfe->ClubManagerTuiFen(pChr);
}

// 游戏中玩家通知俱乐部退分
uint8 GameLogicManager::PlayingPlayerNoticeTuiFen(String strData)
{
	if(strData == "")
		return 0;
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	if(!val.isMember("agent_id") || !val.isMember("gz_id"))
		return 0;
	
	uint32 agent_id = val["agent_id"].asUInt();
	uint32 gz_id = val["gz_id"].asUInt();
	
	String strHttpHost = GetTargetHttpHost(gz_id, agent_id);
	if(strHttpHost == "")
		return 0;
	
	// Url头
	String strUrl = strHttpHost;
	String strParmars = string_url_encode(strData);
	
	strUrl += "player_notice_clubtuifen?";		// Url方法名（管理员退分）
	strUrl += "op=1";							// 操作
	
	uint32 ts = time(0);
	String strTs = StringConverter::toString(ts);
	strUrl += "&ts=";
	strUrl += strTs;							// 时间戳ts
	
	strUrl += "&params=";
	strUrl += strParmars;						// 参数
	
	String strOp = "1";
	CMD5 md5;
	String strSig = md5.GenerateMD5(strOp + strTs + strData + SECUREKEY);
	
	strUrl += "&sig=";
	strUrl += strSig;							// 签名
	Log.Debug("GameLogicManager::PlayingPlayerNoticeTuiFen","strUrl[%s]", strUrl.c_str());
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT);	// 调用url
	Log.Debug("GameLogicManager::PlayingPlayerNoticeTuiFen","recv_result[%s]", recv_result.c_str());
	
	Json::Value valResult;
	reader.parse(recv_result, valResult);
	if(valResult.isMember("status"))
	{
		return valResult["status"].asUInt();
	}
	
	return 1;
}

// 大厅处理玩家退分请求
uint8 GameLogicManager::HallDealPlayerClubTuifen(String strData)
{
	if(strData == "")
		return 0;
	
	Json::Value val;
	Json::Reader reader;
	reader.parse(strData, val);
	
	if(!val.isMember("gz_id") || !val.isMember("pid") || !val.isMember("club_id"))
		return 0;
	
	uint32 gz_id = val["gz_id"].asUInt();
	uint32 pid = val["pid"].asUInt();
	uint32 club_id = val["club_id"].asUInt();
	
	CharPtr pChr = GetCharptrByPidAndGzid(pid, gz_id);
	if(pChr.isNull())
		return 0;
	
	return sCenterClubMgr.PlayerReturnScore(pChr, club_id);
}

// 得到随机头像图标地址
String GameLogicManager::GetRandomHeadIcon(const uint32 & agent_id)
{
	String strTitle = /* sXmlDataMgr.GetGatewayHttpHostAddr(agent_id) */"";
	strTitle += "http://pf.plmpoker.com/platform/getHeadImg";
	
	Log.Debug("GameLogicManager::GetRandomHeadIcon","strTitle[%s]", strTitle.c_str());
	String recv_result = httpd_request(strTitle, REQUIRE_URL_TIMEOUT);
	Log.Debug("GameLogicManager::GetRandomHeadIcon","recv_result[%s]", recv_result.c_str());
	
	Json::Value valResult;
	Json::Reader reader;
	reader.parse(recv_result, valResult);
	
	if(valResult.isMember("images"))
	{
		for (Json::Value::iterator iterVal=valResult["images"].begin(); iterVal!=valResult["images"].end(); ++iterVal)
		{
			return (*iterVal).asString();
		}
	}
	
	return "";
}

// 网关请求充值道具
uint8 GameLogicManager::GatewayOpeartorGoods(String & strParmars, String & return_String)
{
	if(strParmars == "")
		return 0;	// 参数为空
	
	try
	{
		Json::Value val;
		Json::Reader reader;
		reader.parse(strParmars, val);
		
		Log.Debug("GameLogicManager::GatewayOpeartorGoods","strParmars[%s] 111", strParmars.c_str());
		if(!val.isMember("gz_id") || !val.isMember("pid") || !val.isMember("items") || !val.isMember("pay_order"))
			return 2;	// 缺少必要参数之一gz_id,pid,items,pay_order
		
		uint32 gz_id = val["gz_id"].asUInt();
		uint32 pid = val["pid"].asUInt();
		String pay_order = val["pay_order"].asString();
		
		String logMsgHead = "";
		if(val.isMember("msg"))
			logMsgHead = val["msg"].asString();
		
		CharPtr pChr = sGLMgr.GetCharptrByPidAndGzid(pid, gz_id);
		if(pChr.isNull())
			return 3;	// 未找到目标玩家
		
		Json::Value returnVal;
		uint8 index = 0;
		
		for (Json::Value::iterator iterVal=val["items"].begin(); iterVal!=val["items"].end(); ++iterVal)
		{
			uint32 msid = (*iterVal)["msid"].asUInt();
			int32 num = (*iterVal)["num"].asInt();
			if(num < 0)
			{
				if(sGLMgr.GetItemNum(pChr, msid) < uint32(abs(num)))
					return 4;	// 玩家没有那么多道具数量可以扣
			}
		}
		
		bool bAddItem = false;
		String strBuyGoodsInfo = "";
		for (Json::Value::iterator iterVal=val["items"].begin(); iterVal!=val["items"].end(); ++iterVal)
		{
			uint32 msid = (*iterVal)["msid"].asUInt();
			int32 num = (*iterVal)["num"].asInt();
			
			if(num > 0)
			{
				sGLMgr.addItemNum(pChr, msid, uint32(num));
				sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Gateway_Buy, msid, en_UNT_Add, num, 0, 0, 0, logMsgHead);
			}
			else if(num < 0)
			{
				sGLMgr.reduceItemNum(pChr, msid, uint32(abs(num)));
				sLogDataMgr.UpdateItemsInfoLog(pChr, en_ST_Gateway_Buy, msid, en_UNT_Reduce, uint32(abs(num)), 0, 0, 0, logMsgHead);
			}
			
			// 组装邮件里面的商品名称
			strBuyGoodsInfo += GetItemName(msid);
			strBuyGoodsInfo += "x";
			strBuyGoodsInfo += StringConverter::toString(num);
			if(++index < val["items"].size())
				strBuyGoodsInfo += ",";
			
			bAddItem = true;
			
			Json::Value valNewData;
			valNewData["msid"] = msid;
			valNewData["num"] = sGLMgr.GetItemNum(pChr, msid);
			
			returnVal.append(valNewData);
		}
		
		if(bAddItem)
		{// 添加邮件
			String szTitle = "", szContent = "";
			std::map<uint32, uint32> mapItems;
			char buf[256] = "";
			const MailModel * mailM = sXmlDataMgr.GetMailModel("SHOP_BUY_GOODS");
			if(mailM)
			{
				szTitle = mailM->szTitle;
				szContent = mailM->szContent;
				// 恭喜您在【%s】成功购买了：%s。
				sprintf(buf, szContent.c_str(), sGLMgr.GetCurDateTime().c_str(), strBuyGoodsInfo.c_str());
			}
			
			CreateMail(pid, szTitle, buf, 0, en_ST_Gateway_Buy, &mapItems);
			
			Json::FastWriter w;
			return_String = w.write(returnVal);
		}
	}
	catch(exception & e)
	{
		Log.Debug("GameLogicManager::GatewayOpeartorGoods","json parse failed!");
		return 5;	// json转换失败（数字，字符串？）
	}
	
	Log.Debug("GameLogicManager::GatewayOpeartorGoods","return_String[%s] 222", return_String.c_str());
	return 1;
}


// 调用网关玩家离线
/* /platform/usereExit
	METHOD GET
	PARAMS
		ts
		pid
		sig
	RESULT
		true
		false */
void GameLogicManager::SendUrlPlayerExitGame(UserPtr & pUser)
{
	if(pUser.isNull())
		return ;
	
	String strUrl = sXmlDataMgr.GetGatewayHttpHostAddr(pUser->getUInt32Field("reg_from"));
	strUrl += "/platform/userExit?";
	
	// 时间戳
	uint32 cur_time = time(0);
	strUrl += "&ts=";
	strUrl += StringConverter::toString(cur_time);
	
	// pid
	uint32 pid = pUser->getUInt32Field("platform_id");
	strUrl += "&pid=";
	strUrl += StringConverter::toString(pid);
	
	// 签名
	CMD5 md5;
	strUrl += "&sig=";
	strUrl += md5.GenerateMD5(StringConverter::toString(cur_time) + StringConverter::toString(pid) + SERVERINFO_URL_SECRET);
	
	Log.Debug("GameLogicManager::AddPlayerIncomeInfoToUrl","strUrl[%s]", strUrl.c_str());
	String recv_result = httpd_request(strUrl, REQUIRE_URL_TIMEOUT, "POST", strUrl.c_str());
	Log.Debug("GameLogicManager::AddPlayerIncomeInfoToUrl","recv_result[%s]", recv_result.c_str());
}

//=============================算术式解析====================================================
const String Symbol::SymbolList[MAX_FINCE] =
{
	"+","-","*","/","^","s","(",")","%"
};
const int Symbol::SymbolOperatorTypeList[MAX_FINCE] =
{
	2,2,2,2,2,1,0,0,2
};
const int Symbol::SymbolOperatorRankList[MAX_FINCE] =
{
	1,1,2,2,2,2,0,0,2
};
void Symbol::setPos(int _pos)
{
	pos = _pos;
}

Symbol::Symbol(const Symbol & val)
{
	if (val.value)
	{
		switch (val.type)
		{
		case enSymbolType_Int:
		{
			int * temp = new int(*(int*)(val.value));
			value = (void*)temp;
		}
		case enSymbolType_Float:
		{
			float * temp = new float(*(float*)(val.value));
			value = (void*)temp;
		}
		default:
			break;
		}
	}
	pos = val.pos;
	type = val.type;
}

Symbol::Symbol()
{
	value = NULL;
	type = 0;
	pos = -1;
}

Symbol::Symbol(int val, int _pos)
{
	int * temp = new int(val);
	value = (void*)temp;
	type = enSymbolType_Int;
	setPos(_pos);
}

Symbol::Symbol(float val, int _pos)
{
	float * temp = new float(val);
	value = (void*)temp;
	type = enSymbolType_Float;
	setPos(_pos);
}

Symbol::Symbol(String val, int _pos)
{
	while (val.find(' ') != String::npos)
	{
		val.erase(val.find(' '));
	}
	setPos(_pos);
	for (uint8 i = 0; i < MAX_FINCE; i++)
	{
		if (val.compare(SymbolList[i]) == 0)
		{
			type = i + 3;
		}
	}
	if (type == 0)
	{
		if (val.find('.') != String::npos)
		{
			float * temp = new float(StringConverter::parseDouble(val));
			value = (void*)temp;
			type = enSymbolType_Float;
		}
		else
		{
			int * temp = new int(StringConverter::parseInt(val));
			value = (void*)temp;
			type = enSymbolType_Int;
		}
	}
	if (type == 0)
	{
		Log.Error("Symbol", "Create Faild val[%s] _pos[%d]", val.c_str(), _pos);
	}
}

Symbol& Symbol::operator=(int val)
{
	if (value)
	{
		delete value;
	}
	value = NULL;
	value = new int(val);
	return *this;
}

Symbol & Symbol::operator=(float val)
{
	if (value)
	{
		delete value;
	}
	value = NULL;
	value = new float(val);
	return *this;
}

//Symbol & Symbol::operator=(Symbol & val)
//{
//	if (val.value)
//	{
//		switch (val.type)
//		{
//		case enSymbolType_Int:
//		{
//			int * temp = new int(*(int*)(val.value));
//			value = (void*)temp;
//		}
//		case enSymbolType_Float:
//		{
//			float * temp = new float(*(float*)(val.value));
//			value = (void*)temp;
//		}
//		default:
//			break;
//		}
//	}
//	pos = val.pos;
//	type = val.type;
//	return *this;
//}

void Symbol::operator=(const Symbol & val)
{
	if (val.value)
	{
		switch (val.type)
		{
		case enSymbolType_Int:
		{
			int * temp = new int(*(int*)(val.value));
			value = (void*)temp;
		}
		case enSymbolType_Float:
		{
			float * temp = new float(*(float*)(val.value));
			value = (void*)temp;
		}
		default:
			break;
		}
	}
	pos = val.pos;
	type = val.type;
}

int Symbol::GetSymbolOperatorType()
{
	if (type <= enSymbolType_Float)
		return 0;
	else
		return (SymbolOperatorTypeList[type - 3]);
}

int Symbol::GetSymbolOperatorRank()
{
	if (type <= enSymbolType_Float)
		return 0;
	else
		return (SymbolOperatorRankList[type - 3]);
}

bool Symbol::isNumber()
{
	if (type != enSymbolType_Int && type != enSymbolType_Float)
		return false;
	else
		return true;
}

int Symbol::asInt()
{
	return *(int*)value;
}

float Symbol::asFloat()
{
	return *(float*)value;
}

Symbol::~Symbol()
{
	if (value)
	{
		delete value;
	}
	value = NULL;
}

std::pair<int, SymbolFunc_unary> _unaryArray[] = {
	std::make_pair(enSymbolType_ExtractRoot,ExtractRoot),

};
std::map<int, SymbolFunc_unary>  ArithmeticReader::unaryFunc(_unaryArray, _unaryArray + sizeof(_unaryArray) / sizeof(_unaryArray[0]));

std::pair<int, SymbolFunc_binary> _binaryArray[] = {
	std::make_pair(enSymbolType_Addition,Addition),
	std::make_pair(enSymbolType_Subtraction,Subtraction),
	std::make_pair(enSymbolType_Multiplication,Multiplication),
	std::make_pair(enSymbolType_Division,Division),
	std::make_pair(enSymbolType_Power,Power),
	std::make_pair(enSymbolType_Remainder,Remainder),
};
std::map<int, SymbolFunc_binary> ArithmeticReader::binaryFunc(_binaryArray, _binaryArray + sizeof(_binaryArray) / sizeof(_binaryArray[0]));

bool ArithmeticReader::read(String val)
{
	ArithmeticString = val;
	m_vecSymbolList = analyse(val);
	std::map<int, int> ParentheseOrder = GetParentheseOrder(m_vecSymbolList);
	std::map<int, int>::iterator iter, ei = ParentheseOrder.end();
	for (iter = ParentheseOrder.begin(); iter != ei; ++iter)
	{

	}
	return true;
}

bool ArithmeticReader::read(const char * query, ...)
{
	va_list argp;
	va_start(argp, query);
	FieldRows fieldRows;

	char arithmetic[1024] = "";
	va_list vlist;
	va_start(vlist, query);
	vsnprintf(arithmetic, 1024, query, vlist);
	va_end(vlist);
	return read(arithmetic);
}

std::vector<Symbol> ArithmeticReader::analyse(String val)
{
	std::vector<Symbol> result;

	String arithmeticString = val;
	size_t pos = String::npos;
	String operatorStr = "";
	for (uint8 i = 0; i < MAX_FINCE; i++)
	{
		operatorStr += Symbol::SymbolList[i];
	}
	int _index = 0;
	do
	{

		pos = arithmeticString.find_first_of(operatorStr);
		if (pos != String::npos)
		{
			String subarithmetic = arithmeticString.substr(0, pos);
			if (subarithmetic.size() && subarithmetic.find_first_not_of(" ") != String::npos)
			{
				Symbol symbol(subarithmetic, _index++);
				result.push_back(symbol);
			}
			String opStr = arithmeticString.substr(pos,1);
			Symbol opSymbol(opStr, _index++);
			result.push_back(opSymbol);
			arithmeticString = arithmeticString.substr(pos + 1);
		}
		else
		{
			if (arithmeticString.size() && arithmeticString.find_first_not_of(" ") != String::npos)
			{
				Symbol symbol(arithmeticString, _index++);
				result.push_back(symbol);
			}
		}

	} while (pos != String::npos);
	


	return result;
}

std::map<int, int> ArithmeticReader::GetParentheseOrder(std::vector<Symbol> vecSymbolList)
{
	std::map<int, int> result;
	std::queue<int> Parenthesis;
	for (int i = 0; i < vecSymbolList.size(); i++)
	{
		if (vecSymbolList[i].type == enSymbolType_LeftParenthesis)
		{
			Parenthesis.push(i);
		}
		else if (vecSymbolList[i].type == enSymbolType_RightParenthesis)
		{
			result.insert(std::make_pair(Parenthesis.front(), i));
			if (Parenthesis.size())
				Parenthesis.pop();
		}
	}
	return result;
}

Symbol ArithmeticReader::RunArithmetic(std::vector<Symbol> vecSymbol)
{
	Symbol result;
	std::vector<std::vector<uint8> > vecSymbolRankList(10,std::vector<uint8>());
	for (int i = 0; i < vecSymbol.size(); i++)
	{
		if (vecSymbol[i].GetSymbolOperatorRank() != 0)
		{
			vecSymbolRankList[vecSymbol[i].GetSymbolOperatorRank()].push_back(i);
		}
	}
	for (int i = 0; i < vecSymbol.size(); i++)
	{
		if (vecSymbol[i].isNumber())
		{
			result = vecSymbol[i];
			continue;
		}
		if (vecSymbol[i].GetSymbolOperatorType() == enSymbolOperatorType_binary)
		{
			if (i - 1 < 0 || i + 1 >= vecSymbol.size())
			{
				ASSERT(0);
			}
			result = binaryFunc[vecSymbol[i].type](vecSymbol[i - 1], vecSymbol[i + 1]);
		}
		else if (vecSymbol[i].GetSymbolOperatorType() == enSymbolOperatorType_unary)
		{
			if (i + 1 >= vecSymbol.size())
			{
				ASSERT(0);
			}
			result = unaryFunc[vecSymbol[i].type](vecSymbol[i + 1]);
		}
	}
	if (vecSymbol.size() == 1)
		return result;

	return result;
}

Symbol Addition(Symbol a, Symbol b)
{
	Symbol temp;
	temp = a.asFloat() + b.asFloat();
	if (a.type == enSymbolType_Int && b.type == enSymbolType_Int)
		temp.type = enSymbolType_Int;
	return temp;
}

Symbol Subtraction(Symbol a, Symbol b)
{
	Symbol temp;
	temp = a.asFloat() - b.asFloat();
	if (a.type == enSymbolType_Int && b.type == enSymbolType_Int)
		temp.type = enSymbolType_Int;
	return temp;
}

Symbol Multiplication(Symbol a, Symbol b)
{
	Symbol temp;
	temp = a.asFloat() * b.asFloat();
	if (a.type == enSymbolType_Int && b.type == enSymbolType_Int)
		temp.type = enSymbolType_Int;
	return temp;
}

Symbol Division(Symbol a, Symbol b)
{
	Symbol temp;
	temp = a.asFloat() / b.asFloat();
	if (a.type == enSymbolType_Int && b.type == enSymbolType_Int)
		temp.type = enSymbolType_Int;
	return temp;
}

Symbol Power(Symbol a, Symbol b)
{
	Symbol temp;
	temp = std::pow(a.asFloat() ,b.asFloat());
	if (a.type == enSymbolType_Int && b.type == enSymbolType_Int)
		temp.type = enSymbolType_Int;
	return temp;
}

Symbol Remainder(Symbol a, Symbol b)
{
	Symbol temp;
	temp = a.asInt()% b.asInt();
	temp.type = enSymbolType_Int;
	return temp;
}

Symbol ExtractRoot(Symbol a)
{
	Symbol temp;
	temp = std::sqrt(a.asFloat());
	return temp;
}
